Wisp 1.3.1 C++ Unit Test Coverage
Current view: top level - ssrc/wisp/utility - wisp_struct.h (source / functions) Hit Total Coverage
Test: Wisp 1.3.1 C++ Unit Tests Lines: 1 1 100.0 %
Date: 2017-01-16 Functions: 1 1 100.0 %
Branches: 0 0 -

           Branch data     Line data    Source code
       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                 :            : 
      16                 :            : /**
      17                 :            :  * @file
      18                 :            :  * This header defines the WISP_STRUCT generative macro.
      19                 :            :  */
      20                 :            : 
      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                 :            : 
      37                 :            : __BEGIN_NS_SSRC_WISP_UTILITY
      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                 :         22 : struct wisp_struct {
      43                 :            :   template<class Archive> void serialize(Archive & ar, const unsigned int) { }
      44                 :            : };
      45                 :            : 
      46                 :            : __END_NS_SSRC_WISP_UTILITY
      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