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 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*/
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue