Library: need an augmented version of the iterator type rebinding helper
yet another quick-n-dirty hack turned into an useful everyday helper... but at least I need it to be symmetric in and universally applyable
This commit is contained in:
parent
a3a64147c1
commit
60301f7523
4 changed files with 308 additions and 10 deletions
|
|
@ -29,6 +29,7 @@
|
|||
** iterators or custom containers, explicit specialisations
|
||||
** might be injected prior to instantiating the Iterator adapter
|
||||
** template.
|
||||
** @deprecated rework into a generic meta helper 11/2017
|
||||
**
|
||||
** @see iter-adapter.hpp
|
||||
** @see scope-path.hpp usage example (explicit specialisation)
|
||||
|
|
@ -59,7 +60,7 @@ namespace iter {
|
|||
* @note client code might define specialisations
|
||||
* to handle tricky situations (like const_reverse_iter)
|
||||
*/
|
||||
template<typename TY>
|
||||
template<typename TY, typename SEL =void>
|
||||
struct TypeBinding
|
||||
{
|
||||
typedef typename TY::pointer pointer;
|
||||
|
|
@ -115,6 +116,18 @@ namespace iter {
|
|||
typedef size_t* pointer;
|
||||
};
|
||||
|
||||
/**
|
||||
* specialisation for classes providing
|
||||
* STL style type binding definitions themselves
|
||||
*/
|
||||
template<typename TY>
|
||||
struct TypeBinding<TY, typename TY::value_type *>
|
||||
{
|
||||
typedef typename TY::pointer pointer;
|
||||
typedef typename TY::reference reference;
|
||||
typedef typename TY::value_type value_type;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}} // namespace lib
|
||||
|
|
|
|||
117
src/lib/meta/value-type-binding.hpp
Normal file
117
src/lib/meta/value-type-binding.hpp
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
VALUE-TYPE-BINDING.hpp - control type variations for IterAdapter
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2010, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
/** @file value-type-binding.hpp
|
||||
** Type re-binding helper template for IterAdapter and friends.
|
||||
** This header defines a trait template which is used by the Iterator
|
||||
** adapters to figure out the value-, pointer- and reference types
|
||||
** when wrapping iterators or containers. For extending the use of
|
||||
** Iterator adapters and Iter-tools to situations involving const
|
||||
** iterators or custom containers, explicit specialisations
|
||||
** might be injected prior to instantiating the Iterator adapter
|
||||
** template.
|
||||
**
|
||||
** @see iter-adapter.hpp
|
||||
** @see scope-path.hpp usage example (explicit specialisation)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LIB_META_VALUE_TYPE_BINDING_H
|
||||
#define LIB_META_VALUE_TYPE_BINDING_H
|
||||
|
||||
|
||||
#include "lib/error.hpp"
|
||||
|
||||
|
||||
|
||||
namespace std {
|
||||
template<typename _Tp>
|
||||
class shared_ptr;
|
||||
}
|
||||
|
||||
namespace lib {
|
||||
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
|
||||
{
|
||||
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, typename TY::value_type *>
|
||||
{
|
||||
typedef typename TY::pointer pointer;
|
||||
typedef typename TY::reference reference;
|
||||
typedef typename TY::value_type value_type;
|
||||
};
|
||||
|
||||
|
||||
|
||||
}} // namespace lib::meta
|
||||
#endif /*LIB_META_VALUE_TYPE_BINDING_H*/
|
||||
|
|
@ -26,21 +26,13 @@
|
|||
|
||||
|
||||
#include "lib/test/run.hpp"
|
||||
|
||||
//#include "lib/p.hpp"
|
||||
//#include "lib/diff/gen-node.hpp"
|
||||
|
||||
#include "lib/meta/util.hpp"
|
||||
#include "lib/format-cout.hpp"
|
||||
|
||||
#include <iostream> //////////TODO
|
||||
#include <string>
|
||||
|
||||
//using lib::P;
|
||||
//using lib::diff::GenNode;
|
||||
|
||||
using std::string;
|
||||
using std::cout; /////////////TODO
|
||||
using std::endl; /////////////TODO
|
||||
|
||||
|
||||
namespace lib {
|
||||
|
|
|
|||
176
tests/library/meta/value-type-binding-test.cpp
Normal file
176
tests/library/meta/value-type-binding-test.cpp
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
ValueTypeBinding(Test) - human readable simplified display of C++ types
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2017, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
* *****************************************************/
|
||||
|
||||
/** @file type-display-test.cpp
|
||||
** unit test \ref ValueTypeBinding_test
|
||||
*/
|
||||
|
||||
|
||||
#include "lib/test/run.hpp"
|
||||
#include "lib/meta/value-type-binding.hpp"
|
||||
#include "lib/format-cout.hpp"
|
||||
#include "lib/meta/util.hpp" ///////TODO RLY?
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
|
||||
using std::string;/////////////TODO
|
||||
|
||||
|
||||
namespace lib {
|
||||
namespace meta{
|
||||
namespace test{
|
||||
|
||||
namespace { // test fixture
|
||||
|
||||
template<class T>
|
||||
struct Outer
|
||||
{
|
||||
struct Inner
|
||||
{
|
||||
T val;
|
||||
};
|
||||
|
||||
typedef T value_type;
|
||||
typedef Inner const& reference;
|
||||
typedef std::shared_ptr<Inner> pointer;
|
||||
};
|
||||
|
||||
struct Space { };
|
||||
using Join = ulong;
|
||||
|
||||
template<typename X>
|
||||
inline string
|
||||
showType()
|
||||
{
|
||||
return humanReadableTypeID (typeid(X).name());
|
||||
}
|
||||
|
||||
}//(end)fixture
|
||||
|
||||
|
||||
|
||||
|
||||
/**********************************************************************************//**
|
||||
* @test verify result type rebinding for containers, iterators values and references.
|
||||
* When augmenting, combining or decorating generic entities, there is often the need
|
||||
* to find out about the `value_type`, a `reference` or `pointer` to such a value.
|
||||
* Many STL compliant containers and iterators provide suitably nested type definitions
|
||||
* to indicate those types. The meta::TypeBinding helper allows to pick up such
|
||||
* definitions, and additionally it levels and unifies access for various combinations
|
||||
* of primitive types, references and pointers. The purpose of this test is to verify
|
||||
* and document this behaviour.
|
||||
*
|
||||
* @see value-type-binding.hpp
|
||||
* @see lib::RangeIter
|
||||
* @see lib::TreeExplorer::transform()
|
||||
*/
|
||||
class ValueTypeBinding_test
|
||||
: public Test
|
||||
{
|
||||
void
|
||||
run (Arg)
|
||||
{
|
||||
using OuterSpace = Outer<Space>;
|
||||
|
||||
cout << showType<OuterSpace::value_type>() <<endl;
|
||||
cout << showType<OuterSpace::reference>() <<endl;
|
||||
cout << showType<OuterSpace::pointer>() <<endl;
|
||||
|
||||
cout << showType<TypeBinding<OuterSpace>::value_type>() <<endl;
|
||||
cout << showType<TypeBinding<OuterSpace>::reference>() <<endl;
|
||||
cout << showType<TypeBinding<OuterSpace>::pointer>() <<endl;
|
||||
|
||||
cout << showType<TypeBinding<Outer<Join>>::value_type>() <<endl;
|
||||
cout << showType<TypeBinding<Outer<Join>>::reference>() <<endl;
|
||||
cout << showType<TypeBinding<Outer<Join>>::pointer>() <<endl;
|
||||
|
||||
cout << showType<TypeBinding<Space>::value_type>() <<endl;
|
||||
cout << showType<TypeBinding<Space>::reference>() <<endl;
|
||||
cout << showType<TypeBinding<Space>::pointer>() <<endl;
|
||||
|
||||
cout << showType<TypeBinding<OuterSpace&>::value_type>() <<endl;
|
||||
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;
|
||||
cout << showType<TypeBinding<OuterSpace const&>::pointer>() <<endl;
|
||||
|
||||
cout << showType<TypeBinding<OuterSpace*>::value_type>() <<endl;
|
||||
cout << showType<TypeBinding<OuterSpace*>::reference>() <<endl;
|
||||
cout << showType<TypeBinding<OuterSpace*>::pointer>() <<endl;
|
||||
|
||||
cout << showType<TypeBinding<const OuterSpace*>::value_type>() <<endl;
|
||||
cout << showType<TypeBinding<const OuterSpace*>::reference>() <<endl;
|
||||
cout << showType<TypeBinding<const OuterSpace*>::pointer>() <<endl;
|
||||
|
||||
cout << showType<TypeBinding<const OuterSpace * const>::value_type>() <<endl;
|
||||
cout << showType<TypeBinding<const OuterSpace * const>::reference>() <<endl;
|
||||
cout << showType<TypeBinding<const OuterSpace * const>::pointer>() <<endl;
|
||||
|
||||
cout << showType<TypeBinding<OuterSpace * const>::value_type>() <<endl;
|
||||
cout << showType<TypeBinding<OuterSpace * const>::reference>() <<endl;
|
||||
cout << showType<TypeBinding<OuterSpace * const>::pointer>() <<endl;
|
||||
|
||||
cout << showType<TypeBinding<Join>::value_type>() <<endl;
|
||||
cout << showType<TypeBinding<Join>::reference>() <<endl;
|
||||
cout << showType<TypeBinding<Join>::pointer>() <<endl;
|
||||
|
||||
cout << showType<TypeBinding<Join&>::value_type>() <<endl;
|
||||
cout << showType<TypeBinding<Join&>::reference>() <<endl;
|
||||
cout << showType<TypeBinding<Join&>::pointer>() <<endl;
|
||||
|
||||
cout << showType<TypeBinding<Join const&>::value_type>() <<endl;
|
||||
cout << showType<TypeBinding<Join const&>::reference>() <<endl;
|
||||
cout << showType<TypeBinding<Join const&>::pointer>() <<endl;
|
||||
|
||||
cout << showType<TypeBinding<Join *>::value_type>() <<endl;
|
||||
cout << showType<TypeBinding<Join *>::reference>() <<endl;
|
||||
cout << showType<TypeBinding<Join *>::pointer>() <<endl;
|
||||
|
||||
cout << showType<TypeBinding<const Join *>::value_type>() <<endl;
|
||||
cout << showType<TypeBinding<const Join *>::reference>() <<endl;
|
||||
cout << showType<TypeBinding<const Join *>::pointer>() <<endl;
|
||||
|
||||
cout << showType<TypeBinding<const Join * const>::value_type>() <<endl;
|
||||
cout << showType<TypeBinding<const Join * const>::reference>() <<endl;
|
||||
cout << showType<TypeBinding<const Join * const>::pointer>() <<endl;
|
||||
|
||||
cout << showType<TypeBinding<Join * const>::value_type>() <<endl;
|
||||
cout << showType<TypeBinding<Join * const>::reference>() <<endl;
|
||||
cout << showType<TypeBinding<Join * const>::pointer>() <<endl;
|
||||
}
|
||||
};
|
||||
|
||||
LAUNCHER (ValueTypeBinding_test, "unit common");
|
||||
|
||||
|
||||
}}} // namespace lib::meta::test
|
||||
|
||||
Loading…
Reference in a new issue