Skip to content

Commit

Permalink
[#72] cpp::typeerasure::TypeInfo returns type information about funct…
Browse files Browse the repository at this point in the history
…ion parameters
  • Loading branch information
Manu343726 committed Oct 10, 2016
1 parent cbb9eda commit 6a6463e
Show file tree
Hide file tree
Showing 6 changed files with 261 additions and 51 deletions.
6 changes: 3 additions & 3 deletions include/siplasplas/reflection/static/enum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class Enum
/**
* \brief Array type returned by values()
*/
using values_array_t = const EnumType[sizeof...(Constants)];
using values_array_t = cpp::ConstArrayView<EnumType>;

constexpr Enum() = default;

Expand All @@ -96,10 +96,10 @@ class Enum

/**
* \brief Returns the set of enum constants values
* \returns A const reference to a constexpr C array with the EnumType
* \returns A const array view to the enum constants values array
* values
*/
static constexpr const values_array_t& values()
static constexpr values_array_t values()
{
return ::cpp::meta::PackToArray<EnumType, Constants...>::get();
}
Expand Down
57 changes: 40 additions & 17 deletions include/siplasplas/typeerasure/features/valuesemantics.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,40 +100,63 @@ class Constructible
class CopyConstructible
{
public:
template<typename T>
static T apply(const T& value) noexcept(concepts::CopyConstructible<T>::no_except)
template<typename T, bool CopyConstructible = concepts::CopyConstructible<T>::value>
struct Apply
{
return cpp::staticIf<concepts::CopyConstructible<T>::value>([&value](auto identity)
static T apply(const T& value) noexcept(concepts::CopyConstructible<T>::no_except)
{
return meta::type_t<decltype(identity.template type<T>())>(value);
}).Else([](auto) -> T
return T{value};
}

static void apply(T* where, const T& value) noexcept(concepts::CopyConstructible<T>::no_except)
{
return cpp::construct<T>(where, value);
}

static void apply(void* where, const void* other) noexcept(concepts::CopyConstructible<T>::no_except)
{
return cpp::construct<T>(where, *reinterpret_cast<const T*>(other));
}
};

template<typename T>
struct Apply<T, false>
{
static T apply(const T& ealue) noexcept(false)
{
throw cpp::exception<std::runtime_error>(
"Type '{}' is not copy constructible",
ctti::type_id<T>().name()
);
});
}

static void apply(T* where, const T& value) noexcept(false)
{
apply(value);
}

static void apply(void* where, const void* other) noexcept(false)
{
apply(reinterpret_cast<T*>(where), *reinterpret_cast<const T*>(other));
}
};

template<typename T>
static T apply(const T& value) noexcept(concepts::CopyConstructible<T>::no_except)
{
return Apply<T>::apply(value);
}

template<typename T>
static void apply(T* where, const T& value) noexcept(concepts::CopyConstructible<T>::no_except)
{
cpp::staticIf<concepts::CopyConstructible<T>::value>([where, &value](auto identity)
{
cpp::construct<meta::type_t<decltype(identity.template type<T>())>>(where, value);
}).Else([](auto) -> T
{
throw cpp::exception<std::runtime_error>(
"Type '{}' is not copy constructible",
ctti::type_id<T>().name()
);
});
Apply<T>::apply(where, value);
}

template<typename T>
static void apply(void* where, const void* other) noexcept(concepts::CopyConstructible<T>::no_except)
{
apply<T>(reinterpret_cast<T*>(where), *reinterpret_cast<const T*>(other));
Apply<T>::apply(where, other);
}
};

Expand Down
49 changes: 40 additions & 9 deletions include/siplasplas/typeerasure/typeinfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ class TypeInfo : public cpp::TypeInfo
*/
bool isPointer() const
{
return _isPointer;
return cpp::TypeInfo::isPointer();
}

/**
Expand Down Expand Up @@ -214,6 +214,16 @@ class TypeInfo : public cpp::TypeInfo
}
}

/**
* \brief Returns the type information of the function arguments.
*
* The behavior is undefined if the type is not a function type
*/
constexpr cpp::ConstArrayView<TypeInfo> arguments() const
{
return _functionArgs;
}

/**
* \brief Returns the type information of type T
*/
Expand All @@ -223,6 +233,15 @@ class TypeInfo : public cpp::TypeInfo
return TypeInfo{meta::identity<T>()};
}

/**
* \brief Returns the type information of type T
*/
template<typename T>
static constexpr TypeInfo get(const T&)
{
return TypeInfo::get<T>();
}

friend constexpr bool operator==(const TypeInfo& lhs, const TypeInfo& rhs)
{
return lhs._semantics == rhs._semantics;
Expand All @@ -234,20 +253,32 @@ class TypeInfo : public cpp::TypeInfo
}

private:
struct TypeToTypeInfo
{
using value_type = TypeInfo;

template<typename T>
static constexpr TypeInfo get()
{
return TypeInfo::get<T>();
}
};

template<typename T>
constexpr TypeInfo(meta::identity<T>) :
cpp::TypeInfo{cpp::TypeInfo::get<T>()},
_semantics{detail::valueSemanticsOperation<T>},
_isPointer{
std::is_pointer<T>::value &&
cpp::function_kind<T>() != cpp::FunctionKind::FREE_FUNCTION
_semantics{detail::valueSemanticsOperation<std::decay_t<T>>},
_functionArgs{
cpp::meta::SequenceToArray<
cpp::function_arguments<T>,
TypeToTypeInfo
>::get()
}
{
static_assert(alignof(T) < (1 << 16), "Alignment of T cannot be tagged in a pointer, its value overflows a 16 bit unsigned integer");
}
{}

detail::ValueSemantics _semantics;
bool _isPointer;
cpp::ConstArrayView<TypeInfo> _functionArgs;

};

}
Expand Down
1 change: 1 addition & 0 deletions include/siplasplas/utility/function_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ namespace detail
template<typename Function>
struct get_function_signature
{
using args = meta::list<>;
static constexpr FunctionKind kind = FunctionKind::INVALID;
};

Expand Down
Loading

0 comments on commit 6a6463e

Please sign in to comment.