Library: decide on the overall shape of the type rebinding helper

- we do strip references
- we delegate to nested typedefs

Hoever, we do *not* treat const or pointers in any way special --
if the user want to strip or level these, he has to do so explicitly.
Initially it seemed like a good idea to do something clever here, but
on the long run, such "special treatment" is just good for surprises
This commit is contained in:
Fischlurch 2017-11-30 23:19:31 +01:00
parent dce09ebe0d
commit 1047f2f245
2 changed files with 63 additions and 56 deletions

View file

@ -45,10 +45,6 @@
namespace std {
template<typename _Tp>
class shared_ptr;
}
namespace lib { namespace lib {
namespace meta { namespace meta {
@ -75,67 +71,51 @@ namespace meta {
}; };
} }
/**
* Type re-binding helper template for creating nested typedefs
* for use by IterAdapter or similar "Lumiera Forward Iterators".
* This trait provides a value-, reference- and pointer type,
* similar to what the STL does.
* @note client code might define specialisations
* to handle tricky situations (like const_reverse_iter)
*/
template<typename TY, typename SEL =void> template<typename TY, typename SEL =void>
struct TypeBinding struct ValueTypeBinding
{ {
typedef TY value_type; typedef TY value_type;
typedef TY& reference; typedef TY& reference;
typedef TY* pointer; typedef TY* pointer;
}; };
template<typename TY>
struct TypeBinding<TY *>
{
typedef TY value_type;
typedef TY& reference;
typedef TY* pointer;
};
template<typename TY>
struct TypeBinding<const TY *>
{
typedef TY value_type;
typedef const TY& reference;
typedef const TY* pointer;
};
template<typename TY>
struct TypeBinding<TY &>
{
typedef TY value_type;
typedef TY& reference;
typedef TY* pointer;
};
template<typename TY>
struct TypeBinding<TY const&>
{
typedef TY value_type;
typedef const TY& reference;
typedef const TY* pointer;
};
/** /**
* specialisation for classes providing * specialisation for classes providing
* STL style type binding definitions themselves * STL style type binding definitions themselves
*/ */
template<typename TY> template<typename TY>
struct TypeBinding<TY, enable_if<has_nested_ValueTypeBindings<TY>> > struct ValueTypeBinding<TY, enable_if<has_nested_ValueTypeBindings<TY>> >
{ {
typedef typename TY::pointer pointer;
typedef typename TY::reference reference;
typedef typename TY::value_type value_type; typedef typename TY::value_type value_type;
typedef typename TY::reference reference;
typedef typename TY::pointer pointer;
}; };
/**
* Type re-binding helper template for creating nested typedefs
* for use by IterAdapter or similar "Lumiera Forward Iterators".
* This trait provides a value-, reference- and pointer type,
* similar to what the STL does.
* @note client code might define specialisations
* to handle tricky situations (like const_reverse_iter)
*/
template<typename TY>
struct TypeBinding
: ValueTypeBinding<TY>
{ };
template<typename TY>
struct TypeBinding<TY &>
: TypeBinding<TY>
{ };
template<typename TY>
struct TypeBinding<TY &&>
: TypeBinding<TY>
{ };
}} // namespace lib::meta }} // namespace lib::meta
#endif /*LIB_META_VALUE_TYPE_BINDING_H*/ #endif /*LIB_META_VALUE_TYPE_BINDING_H*/

View file

@ -52,8 +52,8 @@ namespace test{
}; };
typedef T value_type; typedef T value_type;
typedef Inner const& reference; typedef Inner & reference;
typedef std::shared_ptr<Inner> pointer; typedef std::shared_ptr<T> pointer;
}; };
struct Space { }; struct Space { };
@ -69,44 +69,72 @@ namespace test{
struct TypeDiagnostics struct TypeDiagnostics
{ {
using Type = X; using Type = X;
static constexpr auto prefix = "";
static constexpr auto postfix = ""; static constexpr auto postfix = "";
}; };
template<typename X> template<typename X>
struct TypeDiagnostics<X&> struct TypeDiagnostics<X&>
{ {
using Type = X; using Type = X;
static constexpr auto prefix = "";
static constexpr auto postfix = "&"; static constexpr auto postfix = "&";
}; };
template<typename X> template<typename X>
struct TypeDiagnostics<X&&> struct TypeDiagnostics<X&&>
{ {
using Type = X; using Type = X;
static constexpr auto prefix = "";
static constexpr auto postfix = " &&"; static constexpr auto postfix = " &&";
}; };
template<typename X> template<typename X>
struct TypeDiagnostics<X const&> struct TypeDiagnostics<X const&>
{ {
using Type = X; using Type = X;
static constexpr auto prefix = "";
static constexpr auto postfix = " const&"; static constexpr auto postfix = " const&";
}; };
template<typename X> template<typename X>
struct TypeDiagnostics<X const&&> struct TypeDiagnostics<X const&&>
{ {
using Type = X; using Type = X;
static constexpr auto postfix = " const &&"; static constexpr auto prefix = "const ";
static constexpr auto postfix = " &&";
}; };
template<typename X> template<typename X>
struct TypeDiagnostics<X *> struct TypeDiagnostics<X *>
{ {
using Type = X; using Type = X;
static constexpr auto prefix = "";
static constexpr auto postfix = " *"; static constexpr auto postfix = " *";
}; };
template<typename X> template<typename X>
struct TypeDiagnostics<const X *>
{
using Type = X;
static constexpr auto prefix = "const ";
static constexpr auto postfix = " *";
};
template<typename X>
struct TypeDiagnostics<const X * const>
{
using Type = X;
static constexpr auto prefix = "const ";
static constexpr auto postfix = " * const";
};
template<typename X>
struct TypeDiagnostics<X * const> struct TypeDiagnostics<X * const>
{ {
using Type = X; using Type = X;
static constexpr auto prefix = "";
static constexpr auto postfix = " * const"; static constexpr auto postfix = " * const";
}; };
template<typename X>
struct TypeDiagnostics<X * const *>
{
using Type = X;
static constexpr auto prefix = "";
static constexpr auto postfix = " * const *";
};
template<typename X> template<typename X>
inline string inline string
@ -115,7 +143,8 @@ namespace test{
using Case = TypeDiagnostics<X>; using Case = TypeDiagnostics<X>;
using Type = typename Case::Type; using Type = typename Case::Type;
return humanReadableTypeID (typeid(Type).name()) return Case::prefix
+ humanReadableTypeID (typeid(Type).name())
+ Case::postfix; + Case::postfix;
} }
@ -166,11 +195,9 @@ namespace test{
cout << showType<TypeBinding<OuterSpace&>::reference>() <<endl; cout << showType<TypeBinding<OuterSpace&>::reference>() <<endl;
cout << showType<TypeBinding<OuterSpace&>::pointer>() <<endl; cout << showType<TypeBinding<OuterSpace&>::pointer>() <<endl;
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #888
cout << showType<TypeBinding<OuterSpace&&>::value_type>() <<endl; cout << showType<TypeBinding<OuterSpace&&>::value_type>() <<endl;
cout << showType<TypeBinding<OuterSpace&&>::reference>() <<endl; cout << showType<TypeBinding<OuterSpace&&>::reference>() <<endl;
cout << showType<TypeBinding<OuterSpace&&>::pointer>() <<endl; cout << showType<TypeBinding<OuterSpace&&>::pointer>() <<endl;
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #888
cout << showType<TypeBinding<OuterSpace const&>::value_type>() <<endl; cout << showType<TypeBinding<OuterSpace const&>::value_type>() <<endl;
cout << showType<TypeBinding<OuterSpace const&>::reference>() <<endl; cout << showType<TypeBinding<OuterSpace const&>::reference>() <<endl;
@ -200,11 +227,9 @@ namespace test{
cout << showType<TypeBinding<Join&>::reference>() <<endl; cout << showType<TypeBinding<Join&>::reference>() <<endl;
cout << showType<TypeBinding<Join&>::pointer>() <<endl; cout << showType<TypeBinding<Join&>::pointer>() <<endl;
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #888
cout << showType<TypeBinding<Join&&>::value_type>() <<endl; cout << showType<TypeBinding<Join&&>::value_type>() <<endl;
cout << showType<TypeBinding<Join&&>::reference>() <<endl; cout << showType<TypeBinding<Join&&>::reference>() <<endl;
cout << showType<TypeBinding<Join&&>::pointer>() <<endl; cout << showType<TypeBinding<Join&&>::pointer>() <<endl;
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #888
cout << showType<TypeBinding<Join const&>::value_type>() <<endl; cout << showType<TypeBinding<Join const&>::value_type>() <<endl;
cout << showType<TypeBinding<Join const&>::reference>() <<endl; cout << showType<TypeBinding<Join const&>::reference>() <<endl;
@ -231,8 +256,10 @@ namespace test{
cout << showType<int&&>() <<endl; cout << showType<int&&>() <<endl;
cout << showType<int const&>() <<endl; cout << showType<int const&>() <<endl;
cout << showType<int const&&>() <<endl; cout << showType<int const&&>() <<endl;
cout << showType<int *>() <<endl;
cout << showType<int const *>() <<endl; cout << showType<int const *>() <<endl;
cout << showType<int const * const>() <<endl; cout << showType<int const * const>() <<endl;
cout << showType<int const * &>() <<endl;
cout << showType<int const * const&>() <<endl; cout << showType<int const * const&>() <<endl;
} }
}; };