Electroneum
variant.h
Go to the documentation of this file.
1 // Copyrights(c) 2017-2021, The Electroneum Project
2 // Copyrights(c) 2014-2019, The Monero Project
3 //
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without modification, are
7 // permitted provided that the following conditions are met:
8 //
9 // 1. Redistributions of source code must retain the above copyright notice, this list of
10 // conditions and the following disclaimer.
11 //
12 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
13 // of conditions and the following disclaimer in the documentation and/or other
14 // materials provided with the distribution.
15 //
16 // 3. Neither the name of the copyright holder nor the names of its contributors may be
17 // used to endorse or promote products derived from this software without specific
18 // prior written permission.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
21 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
28 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
31 
38 #pragma once
39 
40 #include <boost/variant/variant.hpp>
41 #include <boost/variant/apply_visitor.hpp>
42 #include <boost/variant/static_visitor.hpp>
43 #include <boost/mpl/empty.hpp>
44 #include <boost/mpl/if.hpp>
45 #include <boost/mpl/front.hpp>
46 #include <boost/mpl/pop_front.hpp>
47 #include "serialization.h"
48 
55 template <class Archive, class T>
57 {
58 };
59 
64 template <class Archive, class Variant, class TBegin, class TEnd>
66 {
67  typedef typename Archive::variant_tag_type variant_tag_type;
68  typedef typename boost::mpl::next<TBegin>::type TNext;
69  typedef typename boost::mpl::deref<TBegin>::type current_type;
70 
71  // A tail recursive inline function.... okay...
72  static inline bool read(Archive &ar, Variant &v, variant_tag_type t)
73  {
75  current_type x;
76  if(!::do_serialize(ar, x))
77  {
78  ar.stream().setstate(std::ios::failbit);
79  return false;
80  }
81  v = x;
82  } else {
83  // Tail recursive.... but no mutation is going on. Why?
85  }
86  return true;
87  }
88 };
89 
90 // This one just fails when you call it.... okay
91 // So the TEnd parameter must be specified/different from TBegin
92 template <class Archive, class Variant, class TBegin>
93 struct variant_reader<Archive, Variant, TBegin, TBegin>
94 {
95  typedef typename Archive::variant_tag_type variant_tag_type;
96 
97  static inline bool read(Archive &ar, Variant &v, variant_tag_type t)
98  {
99  ar.stream().setstate(std::ios::failbit);
100  return false;
101  }
102 };
103 
104 
105 template <template <bool> class Archive, BOOST_VARIANT_ENUM_PARAMS(typename T)>
106 struct serializer<Archive<false>, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>>
107 {
108  typedef boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> variant_type;
109  typedef typename Archive<false>::variant_tag_type variant_tag_type;
110  typedef typename variant_type::types types;
111 
112  static bool serialize(Archive<false> &ar, variant_type &v) {
114  ar.begin_variant();
115  ar.read_variant_tag(t);
116  if(!variant_reader<Archive<false>, variant_type,
117  typename boost::mpl::begin<types>::type,
118  typename boost::mpl::end<types>::type>::read(ar, v, t))
119  {
120  ar.stream().setstate(std::ios::failbit);
121  return false;
122  }
123  ar.end_variant();
124  return true;
125  }
126 };
127 
128 template <template <bool> class Archive, BOOST_VARIANT_ENUM_PARAMS(typename T)>
129 struct serializer<Archive<true>, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>>
130 {
131  typedef boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> variant_type;
132  //typedef typename Archive<true>::variant_tag_type variant_tag_type;
133 
134  struct visitor : public boost::static_visitor<bool>
135  {
136  Archive<true> &ar;
137 
138  visitor(Archive<true> &a) : ar(a) { }
139 
140  template <class T>
141  bool operator ()(T &rv) const
142  {
143  ar.begin_variant();
144  ar.write_variant_tag(variant_serialization_traits<Archive<true>, T>::get_tag());
145  if(!::do_serialize(ar, rv))
146  {
147  ar.stream().setstate(std::ios::failbit);
148  return false;
149  }
150  ar.end_variant();
151  return true;
152  }
153  };
154 
155  static bool serialize(Archive<true> &ar, variant_type &v) {
156  return boost::apply_visitor(visitor(ar), v);
157  }
158 };
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T)> variant_type
Definition: variant.h:108
Archive::variant_tag_type variant_tag_type
Definition: variant.h:67
const uint32_t T[512]
reads a variant
Definition: variant.h:65
static bool serialize(Archive< false > &ar, variant_type &v)
Definition: variant.h:112
static bool read(Archive &ar, Variant &v, variant_tag_type t)
Definition: variant.h:97
static bool read(Archive &ar, Variant &v, variant_tag_type t)
Definition: variant.h:72
Simple DSL AAPI based on.
return true
static bool serialize(Archive< true > &ar, variant_type &v)
Definition: variant.h:155
#define false
Definition: stdbool.h:38
void do_serialize(boost::mpl::false_, Archive &a, epee::net_utils::network_address &na)
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1124
boost::mpl::deref< TBegin >::type current_type
Definition: variant.h:69
... wouldn&#39;t a class be better?
Definition: serialization.h:92
Archive::variant_tag_type variant_tag_type
Definition: variant.h:95
boost::variant< BOOST_VARIANT_ENUM_PARAMS(T)> variant_type
Definition: variant.h:131
boost::mpl::next< TBegin >::type TNext
Definition: variant.h:68