framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
optional_value.hpp
Go to the documentation of this file.
1 // Copyright (C) 2012 iwg molw5
2 // For conditions of distribution and use, see copyright notice in COPYING
3 
13 #pragma once
14 
15 #include <tuple>
16 #include <cassert>
17 
23 
24 namespace framework
25 {
26  namespace serializable
27  {
32  template <typename T>
34  {
35  private:
36  using implementation = typename T::implementation;
37  using value_type = typename T::value_type;
38 
39  public:
44  value_type const& get () const
45  {
46  assert(static_cast <implementation const*> (this)->check());
47  return p_tValue;
48  }
49 
54  void set (value_type value)
55  {
56  p_tValue = std::move(value);
57  p_bIsSet = true;
58  assert(static_cast <implementation const*> (this)->check());
59  }
60 
64  bool check () const
65  {
66  return p_bIsSet;
67  }
68 
73  void clear ()
74  {
75  p_tValue = value_type{};
76  p_bIsSet = false;
77  assert(!static_cast <implementation const*> (this)->check());
78  }
79 
80  protected:
84  ~default_optional_value () = default;
85 
91  : p_tValue()
92  {
93  assert(!static_cast <implementation const*> (this)->check());
94  }
95 
101  : p_tValue(std::move(value)),
102  p_bIsSet{true}
103  {
104  assert(static_cast <implementation const*> (this)->check());
105  }
106 
110  default_optional_value (std::tuple <>)
112  {
113  }
114 
119  template <typename... Args>
120  default_optional_value (std::tuple <Args&&...>&& args)
122  std::forward <std::tuple <Args&&...>> (args),
123  static_cast <typename make_indices <sizeof... (Args)>::type*> (nullptr))
124  {
125  assert(static_cast <implementation const*> (this)->check());
126  }
127 
128  private:
129  template <typename... Args, typename... Indices>
130  default_optional_value (std::tuple <Args&&...> args, pack_container <Indices...>*)
131  : p_tValue{std::forward <Args> (std::get <Indices::value> (args))...},
132  p_bIsSet{true}
133  {
134  }
135 
136  private:
137  value_type p_tValue {};
138  bool p_bIsSet {false};
139  };
140 
145  template <
146  int64_t Flag,
147  typename Name,
148  typename Specification,
149  template <typename> class Implementation = default_optional_value>
150  struct optional_value : public value_type <
151  Name,
152  Specification,
153  value_implementation_wrapper <
154  Name,
155  Specification,
156  Implementation
157  >::template type,
158  false>
159  {
160  };
161 
172  template <
173  int64_t Flag,
174  typename Name,
175  typename Specification,
176  template <typename> class Implementation,
177  typename Input,
178  typename Output>
181  Input& in, Output& out)
182  {
183  if (!in.check_flag(Flag))
184  {
185  interface <Name> (out).clear();
186  return true;
187  }
188 
190  return dispatch_read <value_alias> (in, out);
191  }
192 
203  template <
204  int64_t Flag,
205  typename Name,
206  typename Specification,
207  template <typename> class Implementation,
208  typename Input,
209  typename Output>
212  Input const& in, Output& out)
213  {
214  if (!interface <Name> (in).check())
215  return true;
216 
218  return dispatch_write <value_alias> (in, out);
219  }
220 
231  template <
232  int64_t Flag,
233  typename Name,
234  typename Specification,
235  template <typename> class Implementation,
236  typename Input,
237  typename Type>
240  Input const& in, output_flags_frame <Type>& out)
241  {
242  if (!interface <Name> (in).check())
243  return true;
244 
245  out.set_flag(Flag);
246 
248  return dispatch_write <value_alias> (in, out);
249  }
250  }
251 }