#ifndef HPP_PMP_TLP
#define HPP_PMP_TLP
///////////////////////////////////////////////////////////////////////////////
// tlp - Template list processing
// Lisp for C++ template metaprogramming
//
// paul@parkscomputing.com
//
// Project web site:
// http://www.parkscomputing.com/tlp/
//
//
// Greenspun's Tenth Rule of Programming: "Any sufficiently complicated C or
// Fortran program contains an ad-hoc, informally-specified bug-ridden slow
// implementation of half of Common Lisp."
//
//
// Copyright (c) 2004, Paul M. Parks
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Paul M. Parks nor the names of other contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
namespace tlp
{
////////////////////////////////////////////////////////////////////////////
// const_value
// value: The constant value supplied, of type T
//
template<int v>
struct const_value
{
enum { value = v };
};
////////////////////////////////////////////////////////////////////////////
// nil
// Represents "nothing"
//
struct nil
{
typedef nil value;
};
////////////////////////////////////////////////////////////////////////////
// tlist
// A list of types
//
template<
class T00=nil,class T01=nil,class T02=nil,class T03=nil,class T04=nil,class T05=nil,class T06=nil,class T07=nil, class T08=nil, class T09=nil,
class T10=nil,class T11=nil,class T12=nil,class T13=nil,class T14=nil,class T15=nil,class T16=nil,class T17=nil, class T18=nil, class T19=nil,
class T20=nil,class T21=nil,class T22=nil,class T23=nil,class T24=nil,class T25=nil,class T26=nil,class T27=nil, class T28=nil, class T29=nil,
class T30=nil,class T31=nil,class T32=nil,class T33=nil,class T34=nil,class T35=nil,class T36=nil,class T37=nil, class T38=nil, class T39=nil,
class T40=nil,class T41=nil,class T42=nil,class T43=nil,class T44=nil,class T45=nil,class T46=nil,class T47=nil, class T48=nil, class T49=nil
>
struct tlist
{
typedef T00 _00;typedef T01 _01;typedef T02 _02;typedef T03 _03;typedef T04 _04;typedef T05 _05;typedef T06 _06;typedef T07 _07;typedef T08 _08;typedef T09 _09;
typedef T10 _10;typedef T11 _11;typedef T12 _12;typedef T13 _13;typedef T14 _14;typedef T15 _15;typedef T16 _16;typedef T17 _17;typedef T18 _18;typedef T19 _19;
typedef T20 _20;typedef T21 _21;typedef T22 _22;typedef T23 _23;typedef T24 _24;typedef T25 _25;typedef T26 _26;typedef T27 _27;typedef T28 _28;typedef T29 _29;
typedef T30 _30;typedef T31 _31;typedef T32 _32;typedef T33 _33;typedef T34 _34;typedef T35 _35;typedef T36 _36;typedef T37 _37;typedef T38 _38;typedef T39 _39;
typedef T40 _40;typedef T41 _41;typedef T42 _42;typedef T43 _43;typedef T44 _44;typedef T45 _45;typedef T46 _46;typedef T47 _47;typedef T48 _48;typedef T49 _49;
typedef tlist<
T00,T01,T02,T03,T04,T05,T06,T07,T08,T09,
T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,
T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,
T30,T31,T32,T33,T34,T35,T36,T37,T38,T39,
T40,T41,T42,T43,T44,T45,T46,T47,T48,T49
> value;
enum { capacity = 50 };
};
typedef tlist<
nil,nil,nil,nil,nil,nil,nil,nil,nil,nil, // 00-09
nil,nil,nil,nil,nil,nil,nil,nil,nil,nil, // 10-19
nil,nil,nil,nil,nil,nil,nil,nil,nil,nil, // 20-29
nil,nil,nil,nil,nil,nil,nil,nil,nil,nil, // 30-39
nil,nil,nil,nil,nil,nil,nil,nil,nil,nil // 40-49
>
nil_list;
////////////////////////////////////////////////////////////////////////////
// t
// Represents "everything"
//
struct t
{
typedef tlist<
t,t,t,t,t,t,t,t,t,t,
t,t,t,t,t,t,t,t,t,t,
t,t,t,t,t,t,t,t,t,t,
t,t,t,t,t,t,t,t,t,t,
t,t,t,t,t,t,t,t,t,t
> value;
};
////////////////////////////////////////////////////////////////////////////
// listp
// value: t if parameter is a tlist, nil otherwise
//
template<class L>
struct listp;
template<
class T00,class T01,class T02,class T03,class T04,class T05,class T06,class T07, class T08, class T09,
class T10,class T11,class T12,class T13,class T14,class T15,class T16,class T17, class T18, class T19,
class T20,class T21,class T22,class T23,class T24,class T25,class T26,class T27, class T28, class T29,
class T30,class T31,class T32,class T33,class T34,class T35,class T36,class T37, class T38, class T39,
class T40,class T41,class T42,class T43,class T44,class T45,class T46,class T47, class T48, class T49
>
struct listp<
tlist<
T00,T01,T02,T03,T04,T05,T06,T07,T08,T09,
T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,
T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,
T30,T31,T32,T33,T34,T35,T36,T37,T38,T39,
T40,T41,T42,T43,T44,T45,T46,T47,T48,T49
>
>
{
typedef t value;
};
template<class L>
struct listp
{
typedef nil value;
};
////////////////////////////////////////////////////////////////////////////
// lnot
// value: negation of parameter
//
template<typename L>
struct lnot;
template<>
struct lnot<nil>
{
typedef t value;
};
template<>
struct lnot<t>
{
typedef nil value;
};
template<>
struct lnot< tlist<nil> >
{
typedef t value;
};
template<
class T00,class T01,class T02,class T03,class T04,class T05,class T06,class T07, class T08, class T09,
class T10,class T11,class T12,class T13,class T14,class T15,class T16,class T17, class T18, class T19,
class T20,class T21,class T22,class T23,class T24,class T25,class T26,class T27, class T28, class T29,
class T30,class T31,class T32,class T33,class T34,class T35,class T36,class T37, class T38, class T39,
class T40,class T41,class T42,class T43,class T44,class T45,class T46,class T47, class T48, class T49
>
struct lnot<
tlist<
T00,T01,T02,T03,T04,T05,T06,T07,T08,T09,
T10,T11,T12,T13,T14,T15,T16,T17,T18,T19,
T20,T21,T22,T23,T24,T25,T26,T27,T28,T29,
T30,T31,T32,T33,T34,T35,T36,T37,T38,T39,
T40,T41,T42,T43,T44,T45,T46,T47,T48,T49
>
>
{
typedef nil value;
};
template<class L>
struct lnot
{
typedef typename lnot<typename L::value>::value value;
};
////////////////////////////////////////////////////////////////////////////
// land
// value: result of boolean evalation
//
template<class LH, class RH>
struct land;
template<class RH>
struct land< nil, RH >
{
typedef nil value;
};
template<class LH>
struct land< LH, nil >
{
typedef nil value;
};
template<class RH>
struct land< tlist<nil>, RH >
{
typedef nil value;
};
template<class LH>
struct land< LH, tlist<nil> >
{
typedef nil value;
};
template<>
struct land< t, t >
{
typedef t value;
};
template<class LH, class RH>
struct land
{
// typedef typename and< typename LH::value, typename RH::value >::value value;
typedef typename RH::value value;
};
////////////////////////////////////////////////////////////////////////////
// lor
// value: result of boolean evalation
//
template<class LH, class RH>
struct lor;
template<>
struct lor< nil, nil >
{
typedef nil value;
};
template<>
struct lor< tlist<nil>, tlist<nil> >
{
typedef nil value;
};
template<class LH, class RH>
struct lor
{
// typedef typename or< typename LH::value, typename RH::value>::value value;
typedef typename LH::value value;
};
////////////////////////////////////////////////////////////////////////////
// quote
// value: The tlist being quoted
//
template<class L>
struct quote
{
typedef L value;
};
////////////////////////////////////////////////////////////////////////////
// car
// value: A tlist containing the first element of the supplied tlist
//
template<class L>
struct car
{
typedef typename L::value::_00 value;
};
////////////////////////////////////////////////////////////////////////////
// cdr
// value: A tlist containing all elements of the supplied tlist
// except the first
//
template<class L>
struct cdr
{
typedef tlist<
typename L::value::_01, typename L::value::_02, typename L::value::_03, typename L::value::_04, typename L::value::_05, typename L::value::_06, typename L::value::_07, typename L::value::_08, typename L::value::_09,
typename L::value::_10, typename L::value::_11, typename L::value::_12, typename L::value::_13, typename L::value::_14, typename L::value::_15, typename L::value::_16, typename L::value::_17, typename L::value::_18, typename L::value::_19,
typename L::value::_20, typename L::value::_21, typename L::value::_22, typename L::value::_23, typename L::value::_24, typename L::value::_25, typename L::value::_26, typename L::value::_27, typename L::value::_28, typename L::value::_29,
typename L::value::_30, typename L::value::_31, typename L::value::_32, typename L::value::_33, typename L::value::_34, typename L::value::_35, typename L::value::_36, typename L::value::_37, typename L::value::_38, typename L::value::_39,
typename L::value::_40, typename L::value::_41, typename L::value::_42, typename L::value::_43, typename L::value::_44, typename L::value::_45, typename L::value::_46, typename L::value::_47, typename L::value::_48, typename L::value::_49
> value;
};
////////////////////////////////////////////////////////////////////////////
// cons
// value: a tlist containing both supplied lists
//
template<class T00, class L>
struct cons
{
typedef tlist<
T00,
typename L::_00,typename L::_01,typename L::_02,typename L::_03,typename L::_04,typename L::_05,typename L::_06,typename L::_07,typename L::_08,typename L::_09,
typename L::_10,typename L::_11,typename L::_12,typename L::_13,typename L::_14,typename L::_15,typename L::_16,typename L::_17,typename L::_18,typename L::_19,
typename L::_20,typename L::_21,typename L::_22,typename L::_23,typename L::_24,typename L::_25,typename L::_26,typename L::_27,typename L::_28,typename L::_29,
typename L::_30,typename L::_31,typename L::_32,typename L::_33,typename L::_34,typename L::_35,typename L::_36,typename L::_37,typename L::_38,typename L::_39,
typename L::_40,typename L::_41,typename L::_42,typename L::_43,typename L::_44,typename L::_45,typename L::_46,typename L::_47,typename L::_48
> value;
};
////////////////////////////////////////////////////////////////////////////
// eq
// value: non-zero (true) if types are identical, zero (false) otherwise
//
template<class LH, class RH>
struct eq;
template<class T>
struct eq<T,T>
{
typedef t value;
};
template<class LH, class RH>
struct eq
{
typedef nil value;
};
////////////////////////////////////////////////////////////////////////////
// length
// value: The length of the supplied tlist
//
template<class L>
struct length;
template<> struct length<nil>
{
enum { value = 0 };
};
template<> struct length<nil_list>
{
enum { value = 0 };
};
template<class L>
struct length
{
enum { value = 1 + length< cdr<L>::value >::value };
};
////////////////////////////////////////////////////////////////////////////
// lt
// value: non-zero (true) if LH < RH, zero (false) otherwise
//
template<int LH, int RH>
struct lt
{
enum { value = (LH < RH) ? 1 : 0 };
};
////////////////////////////////////////////////////////////////////////////
// lt_eq
// value: non-zero (true) if LH <= RH, zero (false) otherwise
//
template<int LH, int RH>
struct lt_eq
{
enum { value = (LH <= RH) ? 1 : 0 };
};
////////////////////////////////////////////////////////////////////////////
// gt
// value: non-zero (true) if LH > RH, zero (false) otherwise
//
template<int LH, int RH>
struct gt
{
enum { value = (LH > RH) ? 1 : 0 };
};
////////////////////////////////////////////////////////////////////////////
// gt_eq
// value: non-zero (true) if LH >= RH, zero (false) otherwise
//
template<int LH, int RH>
struct gt_eq
{
enum { value = (LH >= RH) ? 1 : 0 };
};
////////////////////////////////////////////////////////////////////////////
// add
// value: sum of two integer constants
//
template<int LH, int RH>
struct add
{
enum { value = LH + RH };
};
////////////////////////////////////////////////////////////////////////////
// subtract
// value: difference of two integer constants
//
template<int LH, int RH>
struct subtract
{
enum { value = LH - RH };
};
////////////////////////////////////////////////////////////////////////////
// multiply
// value: product of two integer constants
//
template<int LH, int RH>
struct multiply
{
enum { value = LH * RH };
};
////////////////////////////////////////////////////////////////////////////
// divide
// value: quotient of two integer constants
//
template<int LH, int RH>
struct divide
{
enum { value = LH / RH };
};
////////////////////////////////////////////////////////////////////////////
// nth
// value: Element n of the supplied tlist
//
template<int n, class L>
struct nth;
template<class L>
struct nth<0, L>
{
typedef typename L::value::_00 value;
};
template<int n, class L>
struct nth
{
typedef typename nth< n - 1, typename cdr<L>::value >::value value;
};
////////////////////////////////////////////////////////////////////////////
// first
// value: first element of the supplied tlist
//
template<class L>
struct first
{
typedef typename nth<0, L>::value value;
};
////////////////////////////////////////////////////////////////////////////
// second
// value: second element of the supplied tlist
//
template<class L>
struct second
{
typedef typename nth<1, L>::value value;
};
////////////////////////////////////////////////////////////////////////////
// third
// value: third element of the supplied tlist
//
template<class L>
struct third
{
typedef typename nth<2, L>::value value;
};
////////////////////////////////////////////////////////////////////////////
// fourth
// value: fourth element of the supplied tlist
//
template<class L>
struct fourth
{
typedef typename nth<3, L>::value value;
};
////////////////////////////////////////////////////////////////////////////
// fifth
// value: fifth element of the supplied tlist
//
template<class L>
struct fifth
{
typedef typename nth<4, L>::value value;
};
////////////////////////////////////////////////////////////////////////////
// sixth
// value: sixth element of the supplied tlist
//
template<class L>
struct sixth
{
typedef typename nth<5, L>::value value;
};
////////////////////////////////////////////////////////////////////////////
// seventh
// value: seventh element of the supplied tlist
//
template<class L>
struct seventh
{
typedef typename nth<6, L>::value value;
};
////////////////////////////////////////////////////////////////////////////
// eighth
// value: eighth element of the supplied tlist
//
template<class L>
struct eighth
{
typedef typename nth<7, L>::value value;
};
////////////////////////////////////////////////////////////////////////////
// ninth
// value: ninth element of the supplied tlist
//
template<class L>
struct ninth
{
typedef typename nth<8, L>::value value;
};
////////////////////////////////////////////////////////////////////////////
// tenth
// value: tenth element of the supplied tlist
//
template<class L>
struct tenth
{
typedef typename nth<9, L>::value value;
};
////////////////////////////////////////////////////////////////////////////
// last
// value: last element of the supplied tlist
//
template<class L>
struct last
{
typedef typename
nth<
subtract<
length<L>::value, 1
>::value, L
>::value value;
};
////////////////////////////////////////////////////////////////////////////
// endp
// value: t if the parameter is nil, nil otherwise.
//
template<class L>
struct endp;
template<>
struct endp<nil>
{
typedef t value;
};
template<class L>
struct endp
{
typedef nil value;
};
////////////////////////////////////////////////////////////////////////////
// test
// value:
//
template<class Cond, class IfT, class IfNil = nil>
struct test;
template<class IfT, class IfNil>
struct test<nil, IfT, IfNil>
{
typedef typename IfNil::value value;
};
template<class IfT, class IfNil>
struct test<nil_list, IfT, IfNil>
{
typedef typename IfNil::value value;
};
template<class Cond, class IfT, class IfNil>
struct test
{
typedef typename IfT::value value;
};
////////////////////////////////////////////////////////////////////////////
// cond
// value:
//
template <typename CondList>
struct cond;
template<>
struct cond<nil_list>
{
typedef nil value;
};
template<>
struct cond<nil>
{
typedef nil value;
};
template <typename CondList>
struct cond
{
typedef typename car<CondList>::value lhs;
typedef typename cdr<CondList>::value rhs;
typedef typename first<lhs>::value Cond;
typedef second<lhs> IfT;
typedef cond<rhs> IfNil;
typedef typename test< Cond, IfT, IfNil >::value value;
};
}
#endif // #ifndef HPP_PMP_TLP
|