wisp_struct.h
Go to the documentation of this file.00001 /* 00002 * Copyright 2006-2008 Savarese Software Research Corporation 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.savarese.com/software/ApacheLicense-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00022 #ifndef __SSRC_WISP_UTILITY_WISP_STRUCT_H 00023 #define __SSRC_WISP_UTILITY_WISP_STRUCT_H 00024 00025 #include <boost/preprocessor/punctuation/comma_if.hpp> 00026 #include <boost/preprocessor/control/expr_iif.hpp> 00027 #include <boost/preprocessor/comparison/equal.hpp> 00028 #include <boost/preprocessor/comparison/less_equal.hpp> 00029 #include <boost/preprocessor/comparison/greater_equal.hpp> 00030 #include <boost/preprocessor/seq.hpp> 00031 #include <boost/preprocessor/array/elem.hpp> 00032 #include <boost/preprocessor/array/push_front.hpp> 00033 #include <boost/preprocessor/stringize.hpp> 00034 #include <boost/call_traits.hpp> 00035 00036 #include <ssrc/wisp-packages.h> 00037 00038 __BEGIN_NS_SSRC_WISP_UTILITY 00039 00040 // This is a marker type, from which all WISP_STRUCT's are derived, 00041 // to facilitate metaprogramming 00042 // (e.g., std::is_base_of<wisp_struct, derived_type>). 00043 struct wisp_struct { 00044 template<class Archive> void serialize(Archive & ar, const unsigned int) { } 00045 }; 00046 00047 __END_NS_SSRC_WISP_UTILITY 00048 00049 #define __WISP_STRUCT_MEMBER(r, data, arg) \ 00050 BOOST_PP_TUPLE_ELEM(2, 0, arg) BOOST_PP_TUPLE_ELEM(2, 1, arg); 00051 00052 #define __WISP_STRUCT_DEFAULT_INIT_MEMBER(r, data, i, arg) \ 00053 BOOST_PP_COMMA_IF(i) BOOST_PP_TUPLE_ELEM(2, 1, arg)() 00054 00055 #define __WISP_STRUCT_INIT_MEMBER(r, data, i, arg) \ 00056 BOOST_PP_COMMA_IF(i) BOOST_PP_TUPLE_ELEM(2, 1, arg)(BOOST_PP_TUPLE_ELEM(2, 1, arg)) 00057 00058 #define __WISP_STRUCT_PARAM(r, in_template, i, arg) \ 00059 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) 00060 00061 #define __WISP_STRUCT_PARAM_INIT(r, init, i, arg) \ 00062 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)) 00063 00064 #define __WISP_STRUCT_SERIALIZE(r, data, arg) & BOOST_PP_TUPLE_ELEM(2, 1, arg) 00065 00066 // Serialization 00067 #define __WISP_STRUCT_SERIALIZE_MEMBERS(members) \ 00068 template<class Archive> \ 00069 void serialize(Archive & ar, const unsigned int) { \ 00070 ar BOOST_PP_SEQ_FOR_EACH(__WISP_STRUCT_SERIALIZE, _, members); \ 00071 } \ 00072 00073 // Equality 00074 #define __WISP_STRUCT_EQOP_TEST(r, data, i, arg) \ 00075 BOOST_PP_EXPR_IF(i, &&) (o1.BOOST_PP_TUPLE_ELEM(2, 1, arg) == o2.BOOST_PP_TUPLE_ELEM(2, 1, arg)) 00076 00077 #define __WISP_STRUCT_EQOP(name, seq) \ 00078 friend bool operator==(const name & o1, const name & o2) { \ 00079 return (BOOST_PP_SEQ_FOR_EACH_I(__WISP_STRUCT_EQOP_TEST, _, seq)); \ 00080 } 00081 00082 // Member visitation. Visitor object must implement 00083 // Visitor & operator(const char * const key, const V & value) 00084 // or 00085 // Visitor & operator(const string & key, const V & value) 00086 // (possibly templatized on V) for each type to be visited. 00087 // Non-const value arg versions can be implemented as well if the visitor 00088 // wants to modify the members. Operators return *this to allow chaining. 00089 #define __WISP_STRUCT_VISIT_MEMBERS(r, v, arg) \ 00090 (BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(2, 1, arg)), BOOST_PP_TUPLE_ELEM(2, 1, arg)) 00091 00092 // Swig doesn't understand rvalue references 00093 #ifndef SWIG 00094 #define __WISP_STRUCT_VISIT(members) \ 00095 template<typename Visitor> \ 00096 void visit(Visitor && visitor) { \ 00097 visitor BOOST_PP_SEQ_FOR_EACH(__WISP_STRUCT_VISIT_MEMBERS, visitor, members); \ 00098 } \ 00099 template<typename Visitor> \ 00100 void visit(Visitor && visitor) const { \ 00101 visitor BOOST_PP_SEQ_FOR_EACH(__WISP_STRUCT_VISIT_MEMBERS, visitor, members); \ 00102 } 00103 #else 00104 #define __WISP_STRUCT_VISIT(members) 00105 #endif 00106 00107 // We exclude the struct name { } container for the benefit of client 00108 // code that wants to define its own macros that add extra functionality 00109 // to the generated structures. 00110 #define __WISP_STRUCT(in_template, name, members) \ 00111 BOOST_PP_SEQ_FOR_EACH(__WISP_STRUCT_MEMBER, _, members) \ 00112 name() : \ 00113 BOOST_PP_SEQ_FOR_EACH_I(__WISP_STRUCT_DEFAULT_INIT_MEMBER, _, members) { } \ 00114 explicit name(BOOST_PP_SEQ_FOR_EACH_I(__WISP_STRUCT_PARAM, in_template, members)) : \ 00115 BOOST_PP_SEQ_FOR_EACH_I(__WISP_STRUCT_INIT_MEMBER, _, members) { } \ 00116 __WISP_STRUCT_SERIALIZE_MEMBERS(members) \ 00117 __WISP_STRUCT_EQOP(name, members) \ 00118 __WISP_STRUCT_VISIT(members) 00119 00120 #define __WISP_STRUCT_WITH_INIT(in_template, name, members, initializers) \ 00121 BOOST_PP_SEQ_FOR_EACH(__WISP_STRUCT_MEMBER, _, members) \ 00122 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)) : \ 00123 BOOST_PP_SEQ_FOR_EACH_I(__WISP_STRUCT_INIT_MEMBER, _, members) { } \ 00124 __WISP_STRUCT_SERIALIZE_MEMBERS(members) \ 00125 __WISP_STRUCT_EQOP(name, members) \ 00126 __WISP_STRUCT_VISIT(members) 00127 00128 #define WISP_STRUCT(name, members) \ 00129 struct name : public NS_SSRC_WISP_UTILITY::wisp_struct { __WISP_STRUCT(0, name, members) } 00130 00131 #define WISP_STRUCT_T(name, members) \ 00132 struct name : public NS_SSRC_WISP_UTILITY::wisp_struct { __WISP_STRUCT(1, name, members) } 00133 00134 #define WISP_STRUCT_WITH_INIT(name, members, initializers) \ 00135 struct name : public NS_SSRC_WISP_UTILITY::wisp_struct { __WISP_STRUCT_WITH_INIT(0, name, members, BOOST_PP_SEQ_TO_ARRAY(initializers)) } 00136 00137 #define WISP_STRUCT_WITH_INIT_T(name, members, initializers) \ 00138 struct name : public NS_SSRC_WISP_UTILITY::wisp_struct { __WISP_STRUCT_WITH_INIT(1, name, members, BOOST_PP_SEQ_TO_ARRAY(initializers)) } 00139 00140 #endif
Copyright © 2006-2010 Savarese Software Research Corporation. All rights reserved.
Copyright © 2010 Savarese Software Research Corporation. All rights reserved