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:
Fischlurch 2017-11-30 21:02:36 +01:00
parent a3a64147c1
commit 60301f7523
4 changed files with 308 additions and 10 deletions

View file

@ -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

View 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*/

View file

@ -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 {

View 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