implemented compile-time detection of STL or Lumiera iterator

closes #482
This commit is contained in:
Fischlurch 2010-01-03 05:43:33 +01:00
parent e838d46336
commit 64cedb6345
3 changed files with 124 additions and 21 deletions

View file

@ -170,4 +170,44 @@ namespace lib {
/** Detector for a dereferentiation operator. Works like member detection */
#define META_DETECT_OPERATOR_DEREF() \
template<typename TY> \
class HasOperator_deref \
{ \
template<typename X, int i = sizeof(&X::operator*)> \
struct Probe \
{ }; \
\
template<class X> \
static Yes_t check(Probe<X> * ); \
template<class> \
static No_t check(...); \
\
public: \
static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
};
/** Detector for a prefix increment operator. Works like function detection */
#define META_DETECT_OPERATOR_INC() \
template<typename TY> \
class HasOperator_inc \
{ \
template<typename X, X& (X::*)(void)> \
struct Probe \
{ }; \
\
template<class X> \
static Yes_t check(Probe<X, &X::operator++> * ); \
template<class> \
static No_t check(...); \
\
public: \
static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
};
#endif

View file

@ -356,7 +356,27 @@ out: ::12::11::10::9::8::7::6::5::4::3
END
PLANNED "Iterable type detection" IterableClassification_test <<END
TEST "Iterable type detection" IterableClassification_test <<END
out: can_STL_ForEach<LongVector> : Yes
out: can_STL_ForEach<TimeSet> : Yes
out: can_STL_ForEach<CharMap> : Yes
out: can_STL_ForEach<BoolList> : Yes
out: can_STL_ForEach<ShortDeque> : Yes
out: can_STL_ForEach<CustomCont> : Yes
out: can_STL_ForEach<ForwardRangeIter> : No
out: can_STL_ForEach<TransformedForwardIter> : No
out: can_STL_ForEach<FilteredForwardIter> : No
out: can_STL_ForEach<CustomForwardIter> : No
out: can_IterForEach<LongVector> : No
out: can_IterForEach<TimeSet> : No
out: can_IterForEach<CharMap> : No
out: can_IterForEach<BoolList> : No
out: can_IterForEach<ShortDeque> : No
out: can_IterForEach<CustomCont> : No
out: can_IterForEach<ForwardRangeIter> : Yes
out: can_IterForEach<TransformedForwardIter> : Yes
out: can_IterForEach<FilteredForwardIter> : Yes
out: can_IterForEach<CustomForwardIter> : Yes
END

View file

@ -30,6 +30,9 @@
#include "lib/itertools.hpp"
#include "lib/lumitime.hpp"
/////////////////////////////////////////////////////////////TODO draft
#include <boost/type_traits/is_convertible.hpp>
/////////////////////////////////////////////////////////////TODO draft
#include <iostream>
#include <vector>
#include <deque>
@ -41,16 +44,54 @@
namespace lib {
/////////////////////////////////////////////////////////////TODO draft
template<typename TY>
struct can_STL_ForEach
template<typename T>
class can_STL_ForEach
{
enum{ value = false }; ////////////////TODO unimplemented
struct is_iterable
{
META_DETECT_NESTED(iterator);
META_DETECT_FUNCTION(typename X::iterator, begin,(void));
META_DETECT_FUNCTION(typename X::iterator, end ,(void));
enum { value = HasNested_iterator<T>::value
&& HasFunSig_begin<T>::value
&& HasFunSig_end<T>::value
};
};
struct is_const_iterable
{
META_DETECT_NESTED(const_iterator);
META_DETECT_FUNCTION(typename X::const_iterator, begin,(void) const);
META_DETECT_FUNCTION(typename X::const_iterator, end ,(void) const);
enum { value = HasNested_const_iterator<T>::value
&& HasFunSig_begin<T>::value
&& HasFunSig_end<T>::value
};
};
public:
enum { value = is_iterable::value
|| is_const_iterable::value
};
};
template<typename TY>
struct can_IterForEach
template<typename T>
class can_IterForEach
{
enum{ value = false }; ////////////////TODO unimplemented
META_DETECT_NESTED(value_type);
META_DETECT_OPERATOR_DEREF();
META_DETECT_OPERATOR_INC();
public:
enum{ value = boost::is_convertible<T, bool>::value
&& HasNested_value_type<T>::value
&& HasOperator_deref<T>::value
&& HasOperator_inc<T>::value
};
};
/////////////////////////////////////////////////////////////TODO draft
@ -95,34 +136,38 @@ namespace test{
* Currently (1/10) we're able to detect the following
* - a STL like container with \c begin() and \c end()
* - a Lumiera Forward Iterator
* This test just retrieves the results of a compile time execution
* of the type detection; thus we just define types and then access
* the generated meta function value.
*/
class IterableClassification_test : public Test
{
void
run (Arg)
{
// define a bunch of STL containers
typedef std::vector<long> LongVector;
typedef std::multiset<Time> TimeSet;
typedef std::map<int,char> CharMap;
typedef std::list<bool> BoolList;
typedef std::deque<ushort> ShortDeque;
typedef TestSource CustomContainer;
typedef TestSource CustomCont;
// some types in compliance to the "Lumiera Forward Iterator" concept
typedef TestSource::iterator ForwardRangeIter;
typedef TransformIter<ForwardRangeIter, long> TransformedForwardIter;
typedef FilterIter<TransformedForwardIter> FilteredForwardIter;
typedef ScopeQuery<Effect>::iterator CustomForwardIter;
// detect STL iteration
SHOW_CHECK( can_STL_ForEach<LongVector> );
SHOW_CHECK( can_STL_ForEach<TimeSet> );
SHOW_CHECK( can_STL_ForEach<CharMap> );
SHOW_CHECK( can_STL_ForEach<BoolList> );
SHOW_CHECK( can_STL_ForEach<TimeSet> );
SHOW_CHECK( can_STL_ForEach<CharMap> );
SHOW_CHECK( can_STL_ForEach<BoolList> );
SHOW_CHECK( can_STL_ForEach<ShortDeque> );
SHOW_CHECK( can_STL_ForEach<CustomContainer> );
SHOW_CHECK( can_STL_ForEach<CustomCont> );
SHOW_CHECK( can_STL_ForEach<ForwardRangeIter> );
SHOW_CHECK( can_STL_ForEach<TransformedForwardIter> );
@ -131,18 +176,16 @@ namespace test{
// detect Lumiera Forward Iterator
SHOW_CHECK( can_IterForEach<LongVector> );
SHOW_CHECK( can_IterForEach<TimeSet> );
SHOW_CHECK( can_IterForEach<CharMap> );
SHOW_CHECK( can_IterForEach<BoolList> );
SHOW_CHECK( can_IterForEach<TimeSet> );
SHOW_CHECK( can_IterForEach<CharMap> );
SHOW_CHECK( can_IterForEach<BoolList> );
SHOW_CHECK( can_IterForEach<ShortDeque> );
SHOW_CHECK( can_IterForEach<CustomContainer> );
SHOW_CHECK( can_IterForEach<CustomCont> );
SHOW_CHECK( can_IterForEach<ForwardRangeIter> );
SHOW_CHECK( can_IterForEach<TransformedForwardIter> );
SHOW_CHECK( can_IterForEach<FilteredForwardIter> );
SHOW_CHECK( can_IterForEach<CustomForwardIter> );
UNIMPLEMENTED ("the actual type detection code");
}
};