|
Boost Users : |
From: Black Ice (yg-boost-users_at_[hidden])
Date: 2003-08-06 02:19:23
Pls. look the source codde and demo code, you will find a good substitute
for boost.tuple.
Any suggestions are appreciated.
Source code
#ifndef _PROPERTYLIST_HEADER_
#define _PROPERTYLIST_HEADER_
namespace pl{
struct NullType
{
NullType() {}
template<typename T> NullType(const T&) {}
};
template<typename H, typename T>
struct PropertyList
{
typedef H head_type;
typedef T tail_type;
typedef PropertyList<head_type, tail_type> my_type;
PropertyList() : head_value(head_type()), tail_value(tail_type())
{}
template<typename OtherHead, typename OtherTail>
PropertyList(const OtherHead & head, const OtherTail & tail) :
head_value(head), tail_value(tail)
{}
PropertyList(const my_type & other) : head_value(other.head_value),
tail_value(other.tail_value)
{}
void swap(my_type & other)
{
std::swap(head_value, other.head_value);
std::swap(tail_value, other.tail_value);
}
my_type & operator=(const my_type & other)
{
if(this != &other)
{
my_type temp(other);
swap(temp);
}
return *this;
}
head_type head_value;
tail_type tail_value;
};
#define PROPERTYLIST_1(T1) PropertyList<T1, NullType>
template<typename T1>
PROPERTYLIST_1(T1) make_list(const T1 & t1)
{
return PROPERTYLIST_1(T1)(t1, NullType());
}
#define PROPERTYLIST_2(T1, T2) PropertyList<T1, PROPERTYLIST_1(T2) >
template<typename T1, typename T2>
PROPERTYLIST_2(T1, T2) make_list(const T1 & t1, const T2 & t2)
{
return PROPERTYLIST_2(T1, T2)(t1, make_list(t2));
}
#define PROPERTYLIST_3(T1, T2, T3) PropertyList<T1, PROPERTYLIST_2(T2, T3) >
template<typename T1, typename T2, typename T3>
PROPERTYLIST_3(T1, T2, T3) make_list(const T1 & t1, const T2 & t2, const T3
& t3)
{
return PROPERTYLIST_3(T1, T2, T3)(t1, make_list(t2, t3));
}
#define PROPERTYLIST_4(T1, T2, T3, T4) PropertyList<T1, PROPERTYLIST_3(T2,
T3, T4) >
template<typename T1, typename T2, typename T3, typename T4>
PROPERTYLIST_4(T1, T2, T3, T4) make_list(const T1 & t1, const T2 & t2, const
T3 & t3, const T4 & t4)
{
return PROPERTYLIST_4(T1, T2, T3, T4)(t1, make_list(t2, t3, t4));
}
#define PROPERTYLIST_5(T1, T2, T3, T4, T5) PropertyList<T1,
PROPERTYLIST_4(T2, T3, T4, T5) >
template<typename T1, typename T2, typename T3, typename T4, typename T5>
PROPERTYLIST_5(T1, T2, T3, T4, T5) make_list(const T1 & t1, const T2 & t2,
const T3 & t3, const T4 & t4, const T5 & t5)
{
return PROPERTYLIST_5(T1, T2, T3, T4, T5)(t1, make_list(t2, t3, t4, t5));
}
#define PROPERTYLIST_6(T1, T2, T3, T4, T5, T6) PropertyList<T1,
PROPERTYLIST_5(T2, T3, T4, T5, T6) >
template<typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6>
PROPERTYLIST_6(T1, T2, T3, T4, T5, T6) make_list(const T1 & t1, const T2 &
t2, const T3 & t3, const T4 & t4, const T5 & t5,
const T6 & t6)
{
return PROPERTYLIST_6(T1, T2, T3, T4, T5, T6)(t1, make_list(t2, t3, t4, t5,
t6));
}
#define PROPERTYLIST_7(T1, T2, T3, T4, T5, T6, T7) PropertyList<T1,
PROPERTYLIST_6(T2, T3, T4, T5, T6, T7) >
template<typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7>
PROPERTYLIST_7(T1, T2, T3, T4, T5, T6, T7) make_list(const T1 & t1, const T2
& t2, const T3 & t3, const T4 & t4, const T5 & t5,
const T6 & t6, const T7 & t7)
{
return PROPERTYLIST_7(T1, T2, T3, T4, T5, T6, T7)(t1, make_list(t2, t3, t4,
t5, t6, t7));
}
#define PROPERTYLIST_8(T1, T2, T3, T4, T5, T6, T7, T8) PropertyList<T1,
PROPERTYLIST_7(T2, T3, T4, T5, T6, T7, T8) >
template<typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8>
PROPERTYLIST_8(T1, T2, T3, T4, T5, T6, T7, T8) make_list(const T1 & t1,
const T2 & t2, const T3 & t3, const T4 & t4, const T5 & t5,
const T6 & t6, const T7 & t7, const T8 & t8)
{
return PROPERTYLIST_8(T1, T2, T3, T4, T5, T6, T7, T8)(t1, make_list(t2, t3,
t4, t5, t6, t7, t8));
}
#define PROPERTYLIST_9(T1, T2, T3, T4, T5, T6, T7, T8, T9) PropertyList<T1,
PROPERTYLIST_8(T2, T3, T4, T5, T6, T7, T8, T9) >
template<typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9>
PROPERTYLIST_9(T1, T2, T3, T4, T5, T6, T7, T8, T9) make_list(const T1 & t1,
const T2 & t2, const T3 & t3, const T4 & t4, const T5 & t5,
const T6 & t6, const T7 & t7, const T8 & t8, const T9 & t9)
{
return PROPERTYLIST_9(T1, T2, T3, T4, T5, T6, T7, T8, T9)(t1, make_list(t2,
t3, t4, t5, t6, t7, t8, t9));
}
#define PROPERTYLIST_10(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)
PropertyList<T1, PROPERTYLIST_9(T2, T3, T4, T5, T6, T7, T8, T9, T10) >
template<typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8, typename T9, typename T10>
PROPERTYLIST_10(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) make_list(const T1
& t1, const T2 & t2, const T3 & t3, const T4 & t4, const T5 & t5,
const T6 & t6, const T7 & t7, const T8 & t8, const T9 & t9,
const T10 & t10)
{
return PROPERTYLIST_10(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)(t1,
make_list(t2, t3, t4, t5, t6, t7, t8, t9, t10));
}
template <class PList> struct Length
{
enum{value = 1 + Length<PList::tail_type>::value};
};
template <> struct Length<NullType>
{
enum{value = 0};
};
template<class PList, unsigned int N> struct TypeAt
{
typedef typename TypeAt<typename PList::tail_type, N-1>::type type;
};
template<class PList> struct TypeAt<PList, 0>
{
typedef typename PList::head_type type;
};
template<int N> struct TypeAt<NullType, N>
{
};
template<> struct TypeAt<NullType, 0>
{
typedef NullType type;
};
template<class PList, class T> struct Append
{
typedef PropertyList<typename PList::head_type, typename Append< typename
PList::tail_type, T>::type> type;
};
template<class T> struct Append<NullType, T>
{
typedef PropertyList<T, NullType> type;
};
template<class PList, class T> struct Push
{
typedef PropertyList<T, PList> type;
};
template<class PList> struct Pop
{
typedef typename PList::tail_type type;
};
template<class PList, unsigned int N> struct RemoveAt
{
typedef PropertyList<typename PList::head_type, typename RemoveAt<typename
PList::tail_type, N-1>::type> type;
};
template<class PList> struct RemoveAt<PList, 0>
{
typedef typename PList::tail_type type;
};
template<int N> struct RemoveAt<NullType, N>
{
};
template<> struct RemoveAt<NullType, 0>
{
};
template<class PList, class T, unsigned int N> struct InsertAt
{
typedef PropertyList<typename PList::head_type, typename InsertAt<typename
PList::tail_type, T, N-1>::type> type;
};
template<class PList, class T> struct InsertAt<PList, T, 0>
{
typedef PropertyList<T, PList> type;
};
template<class T, unsigned int N> struct InsertAt<NullType, T, N>
{
};
template<class T> struct InsertAt<NullType, T, 0>
{
};
template<class PList, unsigned int N> struct ValueAt
{
static typename TypeAt<PList, N>::type & get(PList & plist)
{
typedef typename PList::tail_type tail_type;
tail_type & tail = plist.tail_value;
return ValueAt<tail_type, N-1>::get(tail);
}
static const typename TypeAt<PList, N>::type & get(const PList & plist)
{
typedef const typename PList::tail_type tail_type;
tail_type & tail = plist.tail_value;
return ValueAt<tail_type, N-1>::get(tail);
}
};
template<class PList> struct ValueAt<PList, 0>
{
static typename TypeAt<PList, 0>::type & get(PList & plist)
{
return plist.head_value;
}
static const typename TypeAt<PList, 0>::type & get(const PList & plist)
{
return plist.head_value;
}
};
template<class PList, template<class> class FunctionClass, typename T =
NullType>
struct Visitor
{
static void for_each(PList & plist, T & t)
{
FunctionClass<typename PList::head_type> f(t);
f(plist.head_value);
typedef typename PList::tail_type tail_type;
Visitor<tail_type, FunctionClass, T>::for_each(plist.tail_value, t);
}
};
template<class PList, template<class> class FunctionClass>
struct Visitor<PList, FunctionClass, NullType>
{
static void for_each(PList & plist)
{
FunctionClass<typename PList::head_type>()(plist.head_value);
typedef typename PList::tail_type tail_type;
Visitor<tail_type, FunctionClass, NullType>::for_each(plist.tail_value);
}
};
template<template<class> class FunctionClass, typename T>
struct Visitor<NullType, FunctionClass, T>
{
static void for_each(NullType & plist, T &)
{
}
};
template<template<class> class FunctionClass>
struct Visitor<NullType, FunctionClass, NullType>
{
static void for_each(NullType & plist)
{
}
};
} // namespace pl
#endif // _PROPERTYLIST_HEADER_
demo code
#include <iostream>
#include <string>
#include <boost/type_traits.hpp>
#include <PropertyList.h>
#include <utility>
using namespace std;
using namespace boost;
using namespace pl;
template<typename T>
struct Dump
{
void operator()(const T & t)
{
cout << t << endl;
}
};
template<typename T>
struct LoadFromStream
{
LoadFromStream(long stream) : m_stream(stream)
{
}
void operator()(T & t)
{
cout << "Load <" << t << "> from stream " << m_stream << endl;
}
long m_stream;
};
template<typename PList>
void SaveToStream(long stream, const PList & plist)
{
cout << "Save <" << plist.head_value << "> to stream " << stream << endl;
SaveToStream(stream, plist.tail_value);
}
template<>
void SaveToStream<NullType>(long stream, const NullType &)
{
}
void test(void)
{
typedef PROPERTYLIST_3(int, long , double) MY_PROPS;
BOOST_STATIC_ASSERT( (Length<MY_PROPS>::value == 3) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS, 0>::type, int>::value) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS, 1>::type, long>::value) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS, 2>::type, double>::value) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS, 3>::type,
NullType>::value) );
typedef Append<MY_PROPS, float>::type MY_PROPS2;
BOOST_STATIC_ASSERT( (Length<MY_PROPS2>::value == 4) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS2, 0>::type, int>::value) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS2, 1>::type, long>::value) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS2, 2>::type,
double>::value) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS2, 3>::type, float>::value) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS2, 4>::type,
NullType>::value) );
typedef Push<MY_PROPS, char>::type MY_PROPS3;
BOOST_STATIC_ASSERT( (Length<MY_PROPS3>::value == 4) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS3, 0>::type, char>::value) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS3, 1>::type, int>::value) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS3, 2>::type, long>::value) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS3, 3>::type,
double>::value) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS3, 4>::type,
NullType>::value) );
typedef Pop<MY_PROPS>::type MY_PROPS4;
BOOST_STATIC_ASSERT( (Length<MY_PROPS4>::value == 2) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS4, 0>::type, long>::value) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS4, 1>::type,
double>::value) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS4, 2>::type,
NullType>::value) );
typedef RemoveAt<MY_PROPS, 1>::type MY_PROPS5;
BOOST_STATIC_ASSERT( (Length<MY_PROPS5>::value == 2) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS5, 0>::type, int>::value) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS5, 1>::type,
double>::value) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS5, 2>::type,
NullType>::value) );
typedef InsertAt<MY_PROPS, short, 1>::type MY_PROPS6;
BOOST_STATIC_ASSERT( (Length<MY_PROPS6>::value == 4) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS6, 0>::type, int>::value) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS6, 1>::type, short>::value) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS6, 2>::type, long>::value) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS6, 3>::type,
double>::value) );
BOOST_STATIC_ASSERT( (is_same<TypeAt<MY_PROPS6, 4>::type,
NullType>::value) );
typedef Append<MY_PROPS, string>::type MY_PROPS7;
MY_PROPS7 props;
ValueAt<MY_PROPS7, 0>::get(props) = 1;
ValueAt<MY_PROPS7, 1>::get(props) = 2;
ValueAt<MY_PROPS7, 2>::get(props) = 3.3;
ValueAt<MY_PROPS7, 3>::get(props) = "Hello World";
Visitor<MY_PROPS7, Dump>::for_each(props);
long stream = 1;
Visitor<MY_PROPS7, LoadFromStream, long>::for_each(props, stream);
MY_PROPS7 props2 = make_list(10, 20L, 3.1415, string("Hello World"));
SaveToStream(stream, props2);
}
-- Regards, Black Ice 请不要回复到我的邮箱 自由(liberty)无非就是这样一种承诺:每个人将会得到一种保障,保障我们可以与 权威、多数、流俗及舆论的影响相抗衡。 http://www.leoliu.net
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net