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
struct PropertyList
{
typedef H head_type;
typedef T tail_type;
typedef PropertyList my_type;
PropertyList() : head_value(head_type()), tail_value(tail_type())
{}
template
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
template<typename T1>
PROPERTYLIST_1(T1) make_list(const T1 & t1)
{
return PROPERTYLIST_1(T1)(t1, NullType());
}
#define PROPERTYLIST_2(T1, T2) PropertyList
template
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
template
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
template
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
template
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
template
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
template
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
template
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
template
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
template
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 + LengthPList::tail_type::value};
};
template <> struct Length<NullType>
{
enum{value = 0};
};
template struct TypeAt
{
typedef typename TypeAt::type type;
};
template<class PList> struct TypeAt
{
typedef typename PList::head_type type;
};
template<int N> struct TypeAt
{
};
template<> struct TypeAt
{
typedef NullType type;
};
template struct Append
{
typedef PropertyList::type> type;
};
template<class T> struct Append
{
typedef PropertyList type;
};
template struct Push
{
typedef PropertyList type;
};
template<class PList> struct Pop
{
typedef typename PList::tail_type type;
};
template struct RemoveAt
{
typedef PropertyList::type> type;
};
template<class PList> struct RemoveAt
{
typedef typename PList::tail_type type;
};
template<int N> struct RemoveAt
{
};
template<> struct RemoveAt
{
};
template struct InsertAt
{
typedef PropertyList::type> type;
};
template struct InsertAt
{
typedef PropertyList type;
};
template struct InsertAt
{
};
template<class T> struct InsertAt
{
};
template struct ValueAt
{
static typename TypeAt::type & get(PList & plist)
{
typedef typename PList::tail_type tail_type;
tail_type & tail = plist.tail_value;
return ValueAt::get(tail);
}
static const typename TypeAt::type & get(const PList & plist)
{
typedef const typename PList::tail_type tail_type;
tail_type & tail = plist.tail_value;
return ValueAt::get(tail);
}
};
template<class PList> struct ValueAt
{
static typename TypeAt::type & get(PList & plist)
{
return plist.head_value;
}
static const typename TypeAt::type & get(const PList & plist)
{
return plist.head_value;
}
};
template
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::for_each(plist.tail_value, t);
}
};
template
struct Visitor
{
static void for_each(PList & plist)
{
FunctionClass<typename PList::head_type>()(plist.head_value);
typedef typename PList::tail_type tail_type;
Visitor::for_each(plist.tail_value);
}
};
template
struct Visitor
{
static void for_each(NullType & plist, T &)
{
}
};
template
struct Visitor
{
static void for_each(NullType & plist)
{
}
};
} // namespace pl
#endif // _PROPERTYLIST_HEADER_
demo code
#include <iostream>
#include <string>
#include
#include
#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::value == 3) );
BOOST_STATIC_ASSERT( (is_same::type, int>::value) );
BOOST_STATIC_ASSERT( (is_same::type, long>::value) );
BOOST_STATIC_ASSERT( (is_same::type, double>::value) );
BOOST_STATIC_ASSERT( (is_same::type,
NullType>::value) );
typedef Append::type MY_PROPS2;
BOOST_STATIC_ASSERT( (Length::value == 4) );
BOOST_STATIC_ASSERT( (is_same::type, int>::value) );
BOOST_STATIC_ASSERT( (is_same::type, long>::value) );
BOOST_STATIC_ASSERT( (is_same::type,
double>::value) );
BOOST_STATIC_ASSERT( (is_same::type, float>::value) );
BOOST_STATIC_ASSERT( (is_same::type,
NullType>::value) );
typedef Push::type MY_PROPS3;
BOOST_STATIC_ASSERT( (Length::value == 4) );
BOOST_STATIC_ASSERT( (is_same::type, char>::value) );
BOOST_STATIC_ASSERT( (is_same::type, int>::value) );
BOOST_STATIC_ASSERT( (is_same::type, long>::value) );
BOOST_STATIC_ASSERT( (is_same::type,
double>::value) );
BOOST_STATIC_ASSERT( (is_same::type,
NullType>::value) );
typedef Pop::type MY_PROPS4;
BOOST_STATIC_ASSERT( (Length::value == 2) );
BOOST_STATIC_ASSERT( (is_same::type, long>::value) );
BOOST_STATIC_ASSERT( (is_same::type,
double>::value) );
BOOST_STATIC_ASSERT( (is_same::type,
NullType>::value) );
typedef RemoveAt::type MY_PROPS5;
BOOST_STATIC_ASSERT( (Length::value == 2) );
BOOST_STATIC_ASSERT( (is_same::type, int>::value) );
BOOST_STATIC_ASSERT( (is_same::type,
double>::value) );
BOOST_STATIC_ASSERT( (is_same::type,
NullType>::value) );
typedef InsertAt::type MY_PROPS6;
BOOST_STATIC_ASSERT( (Length::value == 4) );
BOOST_STATIC_ASSERT( (is_same::type, int>::value) );
BOOST_STATIC_ASSERT( (is_same::type, short>::value) );
BOOST_STATIC_ASSERT( (is_same::type, long>::value) );
BOOST_STATIC_ASSERT( (is_same::type,
double>::value) );
BOOST_STATIC_ASSERT( (is_same::type,
NullType>::value) );
typedef Append::type MY_PROPS7;
MY_PROPS7 props;
ValueAt::get(props) = 1;
ValueAt::get(props) = 2;
ValueAt::get(props) = 3.3;
ValueAt::get(props) = "Hello World";
Visitor::for_each(props);
long stream = 1;
Visitor::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