2009-06-20 23:39:45 +02:00
|
|
|
/*
|
|
|
|
|
TUPLE-DIAGNOSTICS - helper for diagnostics of type tuples
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2009-06-20 23:39:45 +02:00
|
|
|
Copyright (C) Lumiera.org
|
|
|
|
|
2009, Hermann Vosseler <Ichthyostega@web.de>
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2009-06-20 23:39:45 +02:00
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
|
modify it under the terms of the GNU General Public License as
|
2010-12-17 23:28:49 +01:00
|
|
|
published by the Free Software Foundation; either version 2 of
|
|
|
|
|
the License, or (at your option) any later version.
|
|
|
|
|
|
2009-06-20 23:39:45 +02:00
|
|
|
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.
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2009-06-20 23:39:45 +02:00
|
|
|
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.
|
2010-12-17 23:28:49 +01:00
|
|
|
|
2009-06-20 23:39:45 +02:00
|
|
|
* *****************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** @file tuple-diagnostics.hpp
|
|
|
|
|
** an extension to typelist-diagnostics.hpp, allowing to dump the \em contents
|
|
|
|
|
** of a Tuple datatype. Any type defining an operator string() may be printed
|
|
|
|
|
** when used as Tuple member type; special formatting is provided for the
|
|
|
|
|
** Num<int> test types, which makes typelist and tuples of these types
|
|
|
|
|
** a good candidate for unit tests.
|
|
|
|
|
**
|
|
|
|
|
** @see type-tuple-test.cpp
|
|
|
|
|
** @see typelist-manip-test.cpp
|
|
|
|
|
**
|
|
|
|
|
*/
|
|
|
|
|
#ifndef META_TUPLE_DIAGNOSTICS_H
|
|
|
|
|
#define META_TUPLE_DIAGNOSTICS_H
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "meta/typelist-diagnostics.hpp"
|
|
|
|
|
#include "lib/meta/tuple.hpp"
|
|
|
|
|
|
|
|
|
|
#include <boost/utility/enable_if.hpp>
|
2009-06-21 02:03:22 +02:00
|
|
|
#include <boost/lexical_cast.hpp>
|
2009-06-20 23:39:45 +02:00
|
|
|
#include <boost/format.hpp>
|
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
|
|
using std::string;
|
|
|
|
|
using boost::str;
|
|
|
|
|
using boost::format;
|
|
|
|
|
using boost::enable_if;
|
2009-06-21 02:03:22 +02:00
|
|
|
using boost::lexical_cast;
|
2009-06-20 23:39:45 +02:00
|
|
|
using util::unConst;
|
|
|
|
|
|
|
|
|
|
|
2011-12-03 02:56:50 +01:00
|
|
|
namespace lib {
|
|
|
|
|
namespace meta {
|
|
|
|
|
namespace test {
|
2009-06-20 23:39:45 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace { // Diagnostics
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template<int i>
|
|
|
|
|
string
|
|
|
|
|
showTupElement(Num<i> o)
|
|
|
|
|
{
|
|
|
|
|
static format constElm("(%i)");
|
|
|
|
|
static format changedElm("{%i}");
|
|
|
|
|
|
|
|
|
|
return str ( (o.o_==i? constElm:changedElm) % int(o.o_));
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-21 02:03:22 +02:00
|
|
|
string
|
|
|
|
|
showTupElement(int i)
|
|
|
|
|
{
|
|
|
|
|
return lexical_cast<string>(i);
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-20 23:39:45 +02:00
|
|
|
template<typename T>
|
|
|
|
|
string
|
|
|
|
|
showTupElement(T x)
|
|
|
|
|
{
|
|
|
|
|
return string(x);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Helper template which acts as an "accessor".
|
|
|
|
|
* Using the BuildTupleAccessor, we create a linear chain
|
|
|
|
|
* of such TupleElementDisplayers as subclass of a given tuple type.
|
|
|
|
|
* Here this technique is just used for dumping the tuples data fields,
|
|
|
|
|
* but e.g. the control::Closure uses the same principle for manipulating
|
|
|
|
|
* the individual datafields of an function argument tuple.
|
|
|
|
|
*/
|
|
|
|
|
template
|
|
|
|
|
< typename TY
|
|
|
|
|
, class BASE
|
|
|
|
|
, class TUP
|
|
|
|
|
, uint idx
|
|
|
|
|
>
|
|
|
|
|
class TupleElementDisplayer
|
|
|
|
|
: public BASE
|
|
|
|
|
{
|
|
|
|
|
TY & element() { return BASE::template getAt<idx>(); }
|
|
|
|
|
TY const& element() const { return unConst(this)->template getAt<idx>(); }
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
TupleElementDisplayer(TUP const& tuple) : BASE(tuple) {}
|
|
|
|
|
|
|
|
|
|
string
|
2009-06-21 08:38:24 +02:00
|
|
|
dump (string const& prefix ="(") const
|
2009-06-20 23:39:45 +02:00
|
|
|
{
|
|
|
|
|
return BASE::dump (prefix+showTupElement(element())+",");
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<class TUP>
|
|
|
|
|
class TupleElementDisplayer<NullType, TUP, TUP, 0>
|
|
|
|
|
: public TUP
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
TupleElementDisplayer(TUP const& tuple) : TUP(tuple) {}
|
|
|
|
|
|
|
|
|
|
string
|
2009-06-21 08:38:24 +02:00
|
|
|
dump (string const& prefix ="(") const
|
2009-06-20 23:39:45 +02:00
|
|
|
{
|
|
|
|
|
if (1 < prefix.length())
|
|
|
|
|
// removing the trailing comma
|
|
|
|
|
return prefix.substr (0, prefix.length()-1) +")";
|
|
|
|
|
else
|
|
|
|
|
return prefix+")";
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // (END) Diagnostics Helper
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ===== printing Tuple types and contents ===== */
|
|
|
|
|
|
|
|
|
|
template<typename TYPES>
|
2009-06-21 02:03:22 +02:00
|
|
|
typename enable_if< is_TuplePlain<Tuple<TYPES> >,
|
|
|
|
|
string >::type
|
2009-06-20 23:39:45 +02:00
|
|
|
showDump (Tuple<TYPES> const& tuple)
|
|
|
|
|
{
|
|
|
|
|
typedef BuildTupleAccessor<TYPES,TupleElementDisplayer> BuildAccessor;
|
|
|
|
|
typedef typename BuildAccessor::Accessor Displayer;
|
|
|
|
|
|
|
|
|
|
return "...Tuple" + Displayer(tuple).dump();
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-21 02:03:22 +02:00
|
|
|
template<typename TYPES>
|
|
|
|
|
typename enable_if< is_TupleListType<Tuple<TYPES> >,
|
|
|
|
|
string >::type
|
|
|
|
|
showDump (Tuple<TYPES> const& tuple)
|
|
|
|
|
{
|
|
|
|
|
typedef typename Tuple<TYPES>::Type TypeSeq;
|
|
|
|
|
Tuple<TypeSeq> plainTuple (tuple);
|
|
|
|
|
|
|
|
|
|
typedef BuildTupleAccessor<TypeSeq, TupleElementDisplayer> BuildAccessor;
|
|
|
|
|
typedef typename BuildAccessor::Accessor Displayer;
|
|
|
|
|
|
|
|
|
|
return "...Tuple" + Displayer(plainTuple).dump();
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-20 23:39:45 +02:00
|
|
|
template<typename TUP>
|
2009-06-21 02:03:22 +02:00
|
|
|
typename enable_if< is_TuplePlain<TUP>,
|
2009-06-20 23:39:45 +02:00
|
|
|
string >::type
|
|
|
|
|
showType ()
|
|
|
|
|
{
|
|
|
|
|
typedef InstantiateChained<typename TUP::ArgList, Printer, NullP> DumpPrinter;
|
|
|
|
|
return "TYPES-<>"
|
|
|
|
|
+ DumpPrinter::print();
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-21 02:03:22 +02:00
|
|
|
template<typename TUP>
|
|
|
|
|
typename enable_if< is_TupleListType<TUP>,
|
|
|
|
|
string >::type
|
|
|
|
|
showType ()
|
|
|
|
|
{
|
|
|
|
|
typedef InstantiateChained<typename TUP::ArgList, Printer, NullP> DumpPrinter;
|
|
|
|
|
return "TYPES-[]"
|
|
|
|
|
+ DumpPrinter::print();
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-20 23:39:45 +02:00
|
|
|
// see the macros DISPLAY and DUMPVAL defined in typelist-diagnostics.hpp
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-12-03 02:56:50 +01:00
|
|
|
}}} // namespace lib::meta::test
|
2009-06-20 23:39:45 +02:00
|
|
|
#endif
|