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:
parent
dce09ebe0d
commit
1047f2f245
2 changed files with 63 additions and 56 deletions
|
|
@ -45,10 +45,6 @@
|
|||
|
||||
|
||||
|
||||
namespace std {
|
||||
template<typename _Tp>
|
||||
class shared_ptr;
|
||||
}
|
||||
|
||||
namespace lib {
|
||||
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>
|
||||
struct TypeBinding
|
||||
struct ValueTypeBinding
|
||||
{
|
||||
typedef TY value_type;
|
||||
typedef TY& reference;
|
||||
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
|
||||
* STL style type binding definitions themselves
|
||||
*/
|
||||
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::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
|
||||
#endif /*LIB_META_VALUE_TYPE_BINDING_H*/
|
||||
|
|
|
|||
|
|
@ -52,8 +52,8 @@ namespace test{
|
|||
};
|
||||
|
||||
typedef T value_type;
|
||||
typedef Inner const& reference;
|
||||
typedef std::shared_ptr<Inner> pointer;
|
||||
typedef Inner & reference;
|
||||
typedef std::shared_ptr<T> pointer;
|
||||
};
|
||||
|
||||
struct Space { };
|
||||
|
|
@ -69,44 +69,72 @@ namespace test{
|
|||
struct TypeDiagnostics
|
||||
{
|
||||
using Type = X;
|
||||
static constexpr auto prefix = "";
|
||||
static constexpr auto postfix = "";
|
||||
};
|
||||
template<typename X>
|
||||
struct TypeDiagnostics<X&>
|
||||
{
|
||||
using Type = X;
|
||||
static constexpr auto prefix = "";
|
||||
static constexpr auto postfix = "&";
|
||||
};
|
||||
template<typename X>
|
||||
struct TypeDiagnostics<X&&>
|
||||
{
|
||||
using Type = X;
|
||||
static constexpr auto prefix = "";
|
||||
static constexpr auto postfix = " &&";
|
||||
};
|
||||
template<typename X>
|
||||
struct TypeDiagnostics<X const&>
|
||||
{
|
||||
using Type = X;
|
||||
static constexpr auto prefix = "";
|
||||
static constexpr auto postfix = " const&";
|
||||
};
|
||||
template<typename X>
|
||||
struct TypeDiagnostics<X const&&>
|
||||
{
|
||||
using Type = X;
|
||||
static constexpr auto postfix = " const &&";
|
||||
static constexpr auto prefix = "const ";
|
||||
static constexpr auto postfix = " &&";
|
||||
};
|
||||
template<typename X>
|
||||
struct TypeDiagnostics<X *>
|
||||
{
|
||||
using Type = X;
|
||||
static constexpr auto prefix = "";
|
||||
static constexpr auto postfix = " *";
|
||||
};
|
||||
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>
|
||||
{
|
||||
using Type = X;
|
||||
static constexpr auto prefix = "";
|
||||
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>
|
||||
inline string
|
||||
|
|
@ -115,7 +143,8 @@ namespace test{
|
|||
using Case = TypeDiagnostics<X>;
|
||||
using Type = typename Case::Type;
|
||||
|
||||
return humanReadableTypeID (typeid(Type).name())
|
||||
return Case::prefix
|
||||
+ humanReadableTypeID (typeid(Type).name())
|
||||
+ Case::postfix;
|
||||
}
|
||||
|
||||
|
|
@ -166,11 +195,9 @@ namespace test{
|
|||
cout << showType<TypeBinding<OuterSpace&>::reference>() <<endl;
|
||||
cout << showType<TypeBinding<OuterSpace&>::pointer>() <<endl;
|
||||
|
||||
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #888
|
||||
cout << showType<TypeBinding<OuterSpace&&>::value_type>() <<endl;
|
||||
cout << showType<TypeBinding<OuterSpace&&>::reference>() <<endl;
|
||||
cout << showType<TypeBinding<OuterSpace&&>::pointer>() <<endl;
|
||||
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #888
|
||||
|
||||
cout << showType<TypeBinding<OuterSpace const&>::value_type>() <<endl;
|
||||
cout << showType<TypeBinding<OuterSpace const&>::reference>() <<endl;
|
||||
|
|
@ -200,11 +227,9 @@ namespace test{
|
|||
cout << showType<TypeBinding<Join&>::reference>() <<endl;
|
||||
cout << showType<TypeBinding<Join&>::pointer>() <<endl;
|
||||
|
||||
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #888
|
||||
cout << showType<TypeBinding<Join&&>::value_type>() <<endl;
|
||||
cout << showType<TypeBinding<Join&&>::reference>() <<endl;
|
||||
cout << showType<TypeBinding<Join&&>::pointer>() <<endl;
|
||||
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #888
|
||||
|
||||
cout << showType<TypeBinding<Join const&>::value_type>() <<endl;
|
||||
cout << showType<TypeBinding<Join const&>::reference>() <<endl;
|
||||
|
|
@ -231,8 +256,10 @@ namespace test{
|
|||
cout << showType<int&&>() <<endl;
|
||||
cout << showType<int const&>() <<endl;
|
||||
cout << showType<int const&&>() <<endl;
|
||||
cout << showType<int *>() <<endl;
|
||||
cout << showType<int const *>() <<endl;
|
||||
cout << showType<int const * const>() <<endl;
|
||||
cout << showType<int const * &>() <<endl;
|
||||
cout << showType<int const * const&>() <<endl;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue