blob: b2a0fe1e42780e30c38a6550c897cbaf45ec24f4 [file] [log] [blame]
Jeff Thompsona28eed82013-08-22 16:21:10 -07001// Copyright (C) 2004 Arkadiy Vertleyb
2// Copyright (C) 2005 Peder Holt
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
Jeff Thompson3d613fd2013-10-15 15:39:04 -07006#ifndef NDNBOOST_TYPEOF_TEMPLATE_ENCODING_HPP_INCLUDED
7#define NDNBOOST_TYPEOF_TEMPLATE_ENCODING_HPP_INCLUDED
Jeff Thompsona28eed82013-08-22 16:21:10 -07008
9#include <ndnboost/preprocessor/cat.hpp>
10#include <ndnboost/preprocessor/repetition/enum_trailing.hpp>
11#include <ndnboost/preprocessor/control/iif.hpp>
12#include <ndnboost/preprocessor/detail/is_unary.hpp>
13#include <ndnboost/preprocessor/repetition/repeat.hpp>
14#include <ndnboost/preprocessor/tuple/eat.hpp>
15#include <ndnboost/preprocessor/seq/transform.hpp>
16#include <ndnboost/preprocessor/seq/for_each_i.hpp>
17#include <ndnboost/preprocessor/seq/cat.hpp>
18
19#include <ndnboost/typeof/encode_decode.hpp>
20#include <ndnboost/typeof/int_encoding.hpp>
21
22#include <ndnboost/typeof/type_template_param.hpp>
23#include <ndnboost/typeof/integral_template_param.hpp>
24#include <ndnboost/typeof/template_template_param.hpp>
25
26#ifdef __BORLANDC__
Jeff Thompson3d613fd2013-10-15 15:39:04 -070027#define NDNBOOST_TYPEOF_QUALIFY(P) self_t::P
Jeff Thompsona28eed82013-08-22 16:21:10 -070028#else
Jeff Thompson3d613fd2013-10-15 15:39:04 -070029#define NDNBOOST_TYPEOF_QUALIFY(P) P
Jeff Thompsona28eed82013-08-22 16:21:10 -070030#endif
31// The template parameter description, entered by the user,
32// is converted into a polymorphic "object"
33// that is used to generate the code responsible for
34// encoding/decoding the parameter, etc.
35
36// make sure to cat the sequence first, and only then add the prefix.
Jeff Thompson3d613fd2013-10-15 15:39:04 -070037#define NDNBOOST_TYPEOF_MAKE_OBJ(elem) NDNBOOST_PP_CAT(\
38 NDNBOOST_TYPEOF_MAKE_OBJ,\
39 NDNBOOST_PP_SEQ_CAT((_) NDNBOOST_TYPEOF_TO_SEQ(elem))\
Jeff Thompsona28eed82013-08-22 16:21:10 -070040 )
41
Jeff Thompson3d613fd2013-10-15 15:39:04 -070042#define NDNBOOST_TYPEOF_TO_SEQ(tokens) NDNBOOST_TYPEOF_ ## tokens ## _NDNBOOST_TYPEOF
Jeff Thompsona28eed82013-08-22 16:21:10 -070043
Jeff Thompson3d613fd2013-10-15 15:39:04 -070044// NDNBOOST_TYPEOF_REGISTER_TEMPLATE
Jeff Thompsona28eed82013-08-22 16:21:10 -070045
Jeff Thompson3d613fd2013-10-15 15:39:04 -070046#define NDNBOOST_TYPEOF_REGISTER_TEMPLATE_EXPLICIT_ID(Name, Params, Id)\
47 NDNBOOST_TYPEOF_REGISTER_TEMPLATE_IMPL(\
Jeff Thompsona28eed82013-08-22 16:21:10 -070048 Name,\
Jeff Thompson3d613fd2013-10-15 15:39:04 -070049 NDNBOOST_TYPEOF_MAKE_OBJS(NDNBOOST_TYPEOF_TOSEQ(Params)),\
50 NDNBOOST_PP_SEQ_SIZE(NDNBOOST_TYPEOF_TOSEQ(Params)),\
Jeff Thompsona28eed82013-08-22 16:21:10 -070051 Id)
52
Jeff Thompson3d613fd2013-10-15 15:39:04 -070053#define NDNBOOST_TYPEOF_REGISTER_TEMPLATE(Name, Params)\
54 NDNBOOST_TYPEOF_REGISTER_TEMPLATE_EXPLICIT_ID(Name, Params, NDNBOOST_TYPEOF_UNIQUE_ID())
Jeff Thompsona28eed82013-08-22 16:21:10 -070055
Jeff Thompson3d613fd2013-10-15 15:39:04 -070056#define NDNBOOST_TYPEOF_OBJECT_MAKER(s, data, elem)\
57 NDNBOOST_TYPEOF_MAKE_OBJ(elem)
Jeff Thompsona28eed82013-08-22 16:21:10 -070058
Jeff Thompson3d613fd2013-10-15 15:39:04 -070059#define NDNBOOST_TYPEOF_MAKE_OBJS(Params)\
60 NDNBOOST_PP_SEQ_TRANSFORM(NDNBOOST_TYPEOF_OBJECT_MAKER, ~, Params)
Jeff Thompsona28eed82013-08-22 16:21:10 -070061
62// As suggested by Paul Mensonides:
63
Jeff Thompson3d613fd2013-10-15 15:39:04 -070064#define NDNBOOST_TYPEOF_TOSEQ(x)\
65 NDNBOOST_PP_IIF(\
66 NDNBOOST_PP_IS_UNARY(x),\
67 x NDNBOOST_PP_TUPLE_EAT(3), NDNBOOST_PP_REPEAT\
68 )(x, NDNBOOST_TYPEOF_TOSEQ_2, ~)
Jeff Thompsona28eed82013-08-22 16:21:10 -070069
Jeff Thompson3d613fd2013-10-15 15:39:04 -070070#define NDNBOOST_TYPEOF_TOSEQ_2(z, n, _) (class)
Jeff Thompsona28eed82013-08-22 16:21:10 -070071
Jeff Thompson3d613fd2013-10-15 15:39:04 -070072// NDNBOOST_TYPEOF_VIRTUAL
Jeff Thompsona28eed82013-08-22 16:21:10 -070073
Jeff Thompson3d613fd2013-10-15 15:39:04 -070074#define NDNBOOST_TYPEOF_CAT_4(a, b, c, d) NDNBOOST_TYPEOF_CAT_4_I(a, b, c, d)
75#define NDNBOOST_TYPEOF_CAT_4_I(a, b, c, d) a ## b ## c ## d
Jeff Thompsona28eed82013-08-22 16:21:10 -070076
Jeff Thompson3d613fd2013-10-15 15:39:04 -070077#define NDNBOOST_TYPEOF_VIRTUAL(Fun, Obj)\
78 NDNBOOST_TYPEOF_CAT_4(NDNBOOST_TYPEOF_, NDNBOOST_PP_SEQ_HEAD(Obj), _, Fun)
Jeff Thompsona28eed82013-08-22 16:21:10 -070079
Jeff Thompson3d613fd2013-10-15 15:39:04 -070080// NDNBOOST_TYPEOF_SEQ_ENUM[_TRAILING][_1]
Jeff Thompsona28eed82013-08-22 16:21:10 -070081// Two versions provided due to reentrancy issue
82
Jeff Thompson3d613fd2013-10-15 15:39:04 -070083#define NDNBOOST_TYPEOF_SEQ_EXPAND_ELEMENT(z,n,seq)\
84 NDNBOOST_PP_SEQ_ELEM(0,seq) (z,n,NDNBOOST_PP_SEQ_ELEM(n,NDNBOOST_PP_SEQ_ELEM(1,seq)))
Jeff Thompsona28eed82013-08-22 16:21:10 -070085
Jeff Thompson3d613fd2013-10-15 15:39:04 -070086#define NDNBOOST_TYPEOF_SEQ_ENUM(seq,macro)\
87 NDNBOOST_PP_ENUM(NDNBOOST_PP_SEQ_SIZE(seq),NDNBOOST_TYPEOF_SEQ_EXPAND_ELEMENT,(macro)(seq))
Jeff Thompsona28eed82013-08-22 16:21:10 -070088
Jeff Thompson3d613fd2013-10-15 15:39:04 -070089#define NDNBOOST_TYPEOF_SEQ_ENUM_TRAILING(seq,macro)\
90 NDNBOOST_PP_ENUM_TRAILING(NDNBOOST_PP_SEQ_SIZE(seq),NDNBOOST_TYPEOF_SEQ_EXPAND_ELEMENT,(macro)(seq))
Jeff Thompsona28eed82013-08-22 16:21:10 -070091
Jeff Thompson3d613fd2013-10-15 15:39:04 -070092#define NDNBOOST_TYPEOF_SEQ_EXPAND_ELEMENT_1(z,n,seq)\
93 NDNBOOST_PP_SEQ_ELEM(0,seq) (z,n,NDNBOOST_PP_SEQ_ELEM(n,NDNBOOST_PP_SEQ_ELEM(1,seq)))
Jeff Thompsona28eed82013-08-22 16:21:10 -070094
Jeff Thompson3d613fd2013-10-15 15:39:04 -070095#define NDNBOOST_TYPEOF_SEQ_ENUM_1(seq,macro)\
96 NDNBOOST_PP_ENUM(NDNBOOST_PP_SEQ_SIZE(seq),NDNBOOST_TYPEOF_SEQ_EXPAND_ELEMENT_1,(macro)(seq))
Jeff Thompsona28eed82013-08-22 16:21:10 -070097
Jeff Thompson3d613fd2013-10-15 15:39:04 -070098#define NDNBOOST_TYPEOF_SEQ_ENUM_TRAILING_1(seq,macro)\
99 NDNBOOST_PP_ENUM_TRAILING(NDNBOOST_PP_SEQ_SIZE(seq),NDNBOOST_TYPEOF_SEQ_EXPAND_ELEMENT_1,(macro)(seq))
Jeff Thompsona28eed82013-08-22 16:21:10 -0700100
101//
102
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700103#define NDNBOOST_TYPEOF_PLACEHOLDER(z, n, elem)\
104 NDNBOOST_TYPEOF_VIRTUAL(PLACEHOLDER, elem)(elem)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700105
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700106#define NDNBOOST_TYPEOF_PLACEHOLDER_TYPES(z, n, elem)\
107 NDNBOOST_TYPEOF_VIRTUAL(PLACEHOLDER_TYPES, elem)(elem, n)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700108
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700109#define NDNBOOST_TYPEOF_REGISTER_TEMPLATE_ENCODE_PARAM(r, data, n, elem)\
110 NDNBOOST_TYPEOF_VIRTUAL(ENCODE, elem)(elem, n)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700111
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700112#define NDNBOOST_TYPEOF_REGISTER_TEMPLATE_DECODE_PARAM(r, data, n, elem)\
113 NDNBOOST_TYPEOF_VIRTUAL(DECODE, elem)(elem, n)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700114
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700115#define NDNBOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_PAIR(z, n, elem) \
116 NDNBOOST_TYPEOF_VIRTUAL(EXPANDTYPE, elem)(elem) NDNBOOST_PP_CAT(P, n)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700117
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700118#define NDNBOOST_TYPEOF_REGISTER_DEFAULT_TEMPLATE_TYPE(Name,Params,ID)\
119 Name< NDNBOOST_PP_ENUM_PARAMS(NDNBOOST_PP_SEQ_SIZE(Params), P) >
Jeff Thompsona28eed82013-08-22 16:21:10 -0700120
121//Since we are creating an internal decode struct, we need to use different template names, T instead of P.
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700122#define NDNBOOST_TYPEOF_REGISTER_DECODER_TYPE_PARAM_PAIR(z,n,elem) \
123 NDNBOOST_TYPEOF_VIRTUAL(EXPANDTYPE, elem)(elem) NDNBOOST_PP_CAT(T, n)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700124
125//Default template param decoding
126
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700127#define NDNBOOST_TYPEOF_TYPEDEF_DECODED_TEMPLATE_TYPE(Name,Params)\
128 typedef Name<NDNBOOST_PP_ENUM_PARAMS(NDNBOOST_PP_SEQ_SIZE(Params),NDNBOOST_TYPEOF_QUALIFY(P))> type;
Jeff Thompsona28eed82013-08-22 16:21:10 -0700129
130//Branch the decoding
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700131#define NDNBOOST_TYPEOF_TYPEDEF_DECODED_TYPE(Name,Params)\
132 NDNBOOST_PP_IF(NDNBOOST_TYPEOF_HAS_TEMPLATES(Params),\
133 NDNBOOST_TYPEOF_TYPEDEF_DECODED_TEMPLATE_TEMPLATE_TYPE,\
134 NDNBOOST_TYPEOF_TYPEDEF_DECODED_TEMPLATE_TYPE)(Name,Params)
Jeff Thompsona28eed82013-08-22 16:21:10 -0700135
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700136#define NDNBOOST_TYPEOF_REGISTER_TEMPLATE_IMPL(Name, Params, Size, ID)\
137 NDNBOOST_TYPEOF_BEGIN_ENCODE_NS\
138 NDNBOOST_TYPEOF_REGISTER_TEMPLATE_TEMPLATE_IMPL(Name, Params, ID)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700139 template<class V\
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700140 NDNBOOST_TYPEOF_SEQ_ENUM_TRAILING(Params, NDNBOOST_TYPEOF_REGISTER_TEMPLATE_PARAM_PAIR)\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700141 >\
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700142 struct encode_type_impl<V, Name<NDNBOOST_PP_ENUM_PARAMS(Size, P)> >\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700143 {\
144 typedef typename ndnboost::type_of::push_back<V, ndnboost::mpl::size_t<ID> >::type V0;\
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700145 NDNBOOST_PP_SEQ_FOR_EACH_I(NDNBOOST_TYPEOF_REGISTER_TEMPLATE_ENCODE_PARAM, ~, Params)\
146 typedef NDNBOOST_PP_CAT(V, Size) type;\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700147 };\
148 template<class Iter>\
149 struct decode_type_impl<ndnboost::mpl::size_t<ID>, Iter>\
150 {\
151 typedef decode_type_impl<ndnboost::mpl::size_t<ID>, Iter> self_t;\
152 typedef ndnboost::mpl::size_t<ID> self_id;\
153 typedef Iter iter0;\
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700154 NDNBOOST_PP_SEQ_FOR_EACH_I(NDNBOOST_TYPEOF_REGISTER_TEMPLATE_DECODE_PARAM, ~, Params)\
155 NDNBOOST_TYPEOF_TYPEDEF_DECODED_TYPE(Name, Params)\
156 typedef NDNBOOST_PP_CAT(iter, Size) iter;\
Jeff Thompsona28eed82013-08-22 16:21:10 -0700157 };\
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700158 NDNBOOST_TYPEOF_END_ENCODE_NS
Jeff Thompsona28eed82013-08-22 16:21:10 -0700159
Jeff Thompson3d613fd2013-10-15 15:39:04 -0700160#endif//NDNBOOST_TYPEOF_TEMPLATE_ENCODING_HPP_INCLUDED