Remote Call Framework 3.4
variant.hpp
1 
2 //******************************************************************************
3 // RCF - Remote Call Framework
4 //
5 // Copyright (c) 2005 - 2023, Delta V Software. All rights reserved.
6 // https://www.deltavsoft.com
7 //
8 // RCF is distributed under dual licenses - closed source or GPL.
9 // Consult your particular license for conditions of use.
10 //
11 // If you have not purchased a commercial license, you are using RCF under GPL terms.
12 //
13 // Version: 3.4
14 // Contact: support <at> deltavsoft.com
15 //
16 //******************************************************************************
17 
18 #ifndef INCLUDE_SF_VARIANT_HPP
19 #define INCLUDE_SF_VARIANT_HPP
20 
21 #include <boost/variant.hpp>
22 
23 #include <boost/mpl/front.hpp>
24 #include <boost/mpl/pop_front.hpp>
25 #include <boost/mpl/eval_if.hpp>
26 #include <boost/mpl/identity.hpp>
27 #include <boost/mpl/size.hpp>
28 #include <boost/mpl/empty.hpp>
29 
30 namespace SF {
31 
32  class Archive;
33 
34  class VariantSerializer : public boost::static_visitor<>
35  {
36  public:
37  VariantSerializer(SF::Archive &ar) : mAr(ar)
38  {}
39 
40  template<typename T>
41  void operator()(const T &t) const
42  {
43  mAr & t;
44  }
45 
46  private:
47  SF::Archive &mAr;
48  };
49 
50  template<class S>
51  struct VariantDeserializer
52  {
53  struct LoadNull
54  {
55  template<class V>
56  static void invoke(
57  SF::Archive &,
58  int,
59  V &)
60  {}
61  };
62 
63  struct Load
64  {
65  template<class V>
66  static void invoke(
67  SF::Archive & ar,
68  int which,
69  V & v)
70  {
71  using namespace boost::mpl;
72  if (which == 0)
73  {
74  typedef BOOST_DEDUCED_TYPENAME front<S>::type head_type;
75  head_type value;
76  ar & value;
77  v = value;
78  }
79  else
80  {
81  typedef BOOST_DEDUCED_TYPENAME pop_front<S>::type type;
82  VariantDeserializer<type>::load(ar, which - 1, v);
83  }
84  }
85  };
86 
87  template<class V>
88  static void load(
89  SF::Archive & ar,
90  int which,
91  V & v)
92  {
93  using namespace boost::mpl;
94 
95  typedef BOOST_DEDUCED_TYPENAME eval_if<empty<S>,
96  boost::mpl::identity<LoadNull>,
97  boost::mpl::identity<Load>
98  >::type typex;
99 
100  typex::invoke(ar, which, v);
101  }
102 
103  };
104 
105  template< BOOST_VARIANT_ENUM_PARAMS(class T) >
106  void serialize_vc6(
107  SF::Archive & ar,
108  boost::variant< BOOST_VARIANT_ENUM_PARAMS(T) > & v,
109  const unsigned int)
110  {
111  if (ar.isWrite())
112  {
113  ar & int(v.which());
114  VariantSerializer variantSerializer(ar);
115  v.apply_visitor(variantSerializer);
116  }
117  else
118  {
119  int which = 0;
120  ar & which;
121 
122  typedef BOOST_DEDUCED_TYPENAME
123  boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types types;
124 
125  if(which >= boost::mpl::size<types>::value)
126  {
127  RCF::Exception e(
128  RCF::RcfError_VariantDeserialization,
129  which,
130  boost::mpl::size<types>::value);
131 
132  RCF_THROW(e);
133  }
134 
135  VariantDeserializer<types>::load(ar, which, v);
136  }
137  }
138 } // namespace SF
139 
140 #endif // ! INCLUDE_SF_VARIANT_HPP
Represents an archive, in which serialized objects are stored.
Definition: Archive.hpp:31
Base class for all RCF exceptions.
Definition: Exception.hpp:67
Definition: ByteBuffer.hpp:188
bool isWrite() const
Returns true if this archive is being written to.