Savarese Software Research Corporation
wisp_struct.h
Go to the documentation of this file.
1 /* Copyright 2006-2008 Savarese Software Research Corporation
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.savarese.com/software/ApacheLicense-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
21 #ifndef __SSRC_WISP_UTILITY_WISP_STRUCT_H
22 #define __SSRC_WISP_UTILITY_WISP_STRUCT_H
23 
24 #include <boost/preprocessor/punctuation/comma_if.hpp>
25 #include <boost/preprocessor/control/expr_iif.hpp>
26 #include <boost/preprocessor/comparison/equal.hpp>
27 #include <boost/preprocessor/comparison/less_equal.hpp>
28 #include <boost/preprocessor/comparison/greater_equal.hpp>
29 #include <boost/preprocessor/seq.hpp>
30 #include <boost/preprocessor/array/elem.hpp>
31 #include <boost/preprocessor/array/push_front.hpp>
32 #include <boost/preprocessor/stringize.hpp>
33 #include <boost/call_traits.hpp>
34 
35 #include <ssrc/wisp-packages.h>
36 
38 
39 // This is a marker type, from which all WISP_STRUCT's are derived,
40 // to facilitate metaprogramming
41 // (e.g., std::is_base_of<wisp_struct, derived_type>).
42 struct wisp_struct {
43  template<class Archive> void serialize(Archive & ar, const unsigned int) { }
44 };
45 
47 
48 #define __WISP_STRUCT_MEMBER(r, data, arg) \
49  BOOST_PP_TUPLE_ELEM(2, 0, arg) BOOST_PP_TUPLE_ELEM(2, 1, arg);
50 
51 #define __WISP_STRUCT_DEFAULT_INIT_MEMBER(r, data, i, arg) \
52  BOOST_PP_COMMA_IF(i) BOOST_PP_TUPLE_ELEM(2, 1, arg)()
53 
54 #define __WISP_STRUCT_INIT_MEMBER(r, data, i, arg) \
55  BOOST_PP_COMMA_IF(i) BOOST_PP_TUPLE_ELEM(2, 1, arg)(BOOST_PP_TUPLE_ELEM(2, 1, arg))
56 
57 #define __WISP_STRUCT_PARAM(r, in_template, i, arg) \
58  BOOST_PP_COMMA_IF(i) BOOST_PP_EXPR_IIF(in_template, typename) boost::call_traits<BOOST_PP_TUPLE_ELEM(2, 0, arg)>::param_type BOOST_PP_TUPLE_ELEM(2, 1, arg)
59 
60 #define __WISP_STRUCT_PARAM_INIT(r, init, i, arg) \
61  BOOST_PP_COMMA_IF(i) BOOST_PP_EXPR_IIF(BOOST_PP_ARRAY_ELEM(0, init), typename) boost::call_traits<BOOST_PP_TUPLE_ELEM(2, 0, arg)>::param_type BOOST_PP_TUPLE_ELEM(2, 1, arg) BOOST_PP_EXPR_IIF(BOOST_PP_GREATER_EQUAL(i, BOOST_PP_ARRAY_ELEM(1, init)), = BOOST_PP_ARRAY_ELEM(BOOST_PP_SUB(BOOST_PP_ADD(i, 2), BOOST_PP_ARRAY_ELEM(1, init)), init))
62 
63 #define __WISP_STRUCT_SERIALIZE(r, data, arg) & BOOST_PP_TUPLE_ELEM(2, 1, arg)
64 
65 // Serialization
66 #define __WISP_STRUCT_SERIALIZE_MEMBERS(members) \
67  template<class Archive> \
68  void serialize(Archive & ar, const unsigned int) { \
69  ar BOOST_PP_SEQ_FOR_EACH(__WISP_STRUCT_SERIALIZE, _, members); \
70  } \
71 
72 // Equality
73 #define __WISP_STRUCT_EQOP_TEST(r, data, i, arg) \
74  BOOST_PP_EXPR_IF(i, &&) (o1.BOOST_PP_TUPLE_ELEM(2, 1, arg) == o2.BOOST_PP_TUPLE_ELEM(2, 1, arg))
75 
76 #define __WISP_STRUCT_EQOP(name, seq) \
77  friend bool operator==(const name & o1, const name & o2) { \
78  return (BOOST_PP_SEQ_FOR_EACH_I(__WISP_STRUCT_EQOP_TEST, _, seq)); \
79  }
80 
81 // Member visitation. Visitor object must implement
82 // Visitor & operator(const char * const key, const V & value)
83 // or
84 // Visitor & operator(const std::string & key, const V & value)
85 // (possibly templatized on V) for each type to be visited.
86 // Non-const value arg versions can be implemented as well if the visitor
87 // wants to modify the members. Operators return *this to allow chaining.
88 #define __WISP_STRUCT_VISIT_MEMBERS(r, v, arg) \
89  (BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(2, 1, arg)), BOOST_PP_TUPLE_ELEM(2, 1, arg))
90 
91 // Swig doesn't understand rvalue references
92 #ifndef SWIG
93 #define __WISP_STRUCT_VISIT(members) \
94  template<typename Visitor> \
95  void visit(Visitor && visitor) { \
96  visitor BOOST_PP_SEQ_FOR_EACH(__WISP_STRUCT_VISIT_MEMBERS, visitor, members); \
97  } \
98  template<typename Visitor> \
99  void visit(Visitor && visitor) const { \
100  visitor BOOST_PP_SEQ_FOR_EACH(__WISP_STRUCT_VISIT_MEMBERS, visitor, members); \
101  }
102 #else
103 #define __WISP_STRUCT_VISIT(members)
104 #endif
105 
106 // We exclude the struct name { } container for the benefit of client
107 // code that wants to define its own macros that add extra functionality
108 // to the generated structures.
109 #define __WISP_STRUCT(in_template, name, members) \
110  BOOST_PP_SEQ_FOR_EACH(__WISP_STRUCT_MEMBER, _, members) \
111  name() : \
112  BOOST_PP_SEQ_FOR_EACH_I(__WISP_STRUCT_DEFAULT_INIT_MEMBER, _, members) { } \
113  explicit name(BOOST_PP_SEQ_FOR_EACH_I(__WISP_STRUCT_PARAM, in_template, members)) : \
114  BOOST_PP_SEQ_FOR_EACH_I(__WISP_STRUCT_INIT_MEMBER, _, members) { } \
115  __WISP_STRUCT_SERIALIZE_MEMBERS(members) \
116  __WISP_STRUCT_EQOP(name, members) \
117  __WISP_STRUCT_VISIT(members)
118 
119 #define __WISP_STRUCT_WITH_INIT(in_template, name, members, initializers) \
120  BOOST_PP_SEQ_FOR_EACH(__WISP_STRUCT_MEMBER, _, members) \
121  explicit name(BOOST_PP_SEQ_FOR_EACH_I(__WISP_STRUCT_PARAM_INIT, BOOST_PP_ARRAY_PUSH_FRONT(BOOST_PP_ARRAY_PUSH_FRONT(initializers, BOOST_PP_SUB(BOOST_PP_SEQ_SIZE(members), BOOST_PP_ARRAY_SIZE(initializers))), in_template), members)) : \
122  BOOST_PP_SEQ_FOR_EACH_I(__WISP_STRUCT_INIT_MEMBER, _, members) { } \
123  __WISP_STRUCT_SERIALIZE_MEMBERS(members) \
124  __WISP_STRUCT_EQOP(name, members) \
125  __WISP_STRUCT_VISIT(members)
126 
127 #define WISP_STRUCT(name, members) \
128  struct name : public NS_SSRC_WISP_UTILITY::wisp_struct { __WISP_STRUCT(0, name, members) }
129 
130 #define WISP_STRUCT_T(name, members) \
131  struct name : public NS_SSRC_WISP_UTILITY::wisp_struct { __WISP_STRUCT(1, name, members) }
132 
133 #define WISP_STRUCT_WITH_INIT(name, members, initializers) \
134  struct name : public NS_SSRC_WISP_UTILITY::wisp_struct { __WISP_STRUCT_WITH_INIT(0, name, members, BOOST_PP_SEQ_TO_ARRAY(initializers)) }
135 
136 #define WISP_STRUCT_WITH_INIT_T(name, members, initializers) \
137  struct name : public NS_SSRC_WISP_UTILITY::wisp_struct { __WISP_STRUCT_WITH_INIT(1, name, members, BOOST_PP_SEQ_TO_ARRAY(initializers)) }
138 
139 #endif

Savarese Software Research Corporation
Copyright © 2006-2012 Savarese Software Research Corporation. All rights reserved.