Minsky
optional.h
Go to the documentation of this file.
1 /*
2  @copyright Steve Keen 2020
3  @author Russell Standish
4  This file is part of Minsky.
5 
6  Minsky is free software: you can redistribute it and/or modify it
7  under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Minsky is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with Minsky. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #ifndef MINSKY_OPTIONAL_H
21 #define MINSKY_OPTIONAL_H
22 #include <xsd_generate_base.h>
23 #include <memory>
24 
25 namespace minsky
26 {
27 // see discussion in Stroustrup 4th ed 28.4.4
28  template <class T> struct has_empty
29  {
30  template <class X>
31  static auto check(X x)->decltype(x.empty());
32  static std::false_type check(...);
33 
34  static constexpr const bool value = std::is_integral<decltype(check(std::declval<T>()))>::value;
35  };
36 
38  template <class T>
39  struct Optional: shared_ptr<T>
40  {
41  Optional() {}
42  Optional(const T& x) {assign(x);}
43  template <class U>
44  Optional(const Optional<U>& x) {if (x) *this=*x;}
45  template <class U>
46  typename classdesc::enable_if<has_empty<U>,void>::T
47  assign(const U& x, classdesc::dummy<0> d=0) {
48  if (!x.empty()) this->reset(new T(x));
49  }
50  template <class U>
51  typename classdesc::enable_if<classdesc::Not<has_empty<U>>,void>::T
52  assign(const U& x, classdesc::dummy<1> d=0) {this->reset(new T(x));}
53 
54  // if we access an optional, then create its target
55  T& operator*() {if (!this->get()) this->reset(new T); return *this->get();}
56  const T& operator*() const {return *this->get();}
57  T* operator->() {return &**this;}
58  const T* operator->() const {return &**this;}
59 
60  template <class U> Optional& operator=(const U& x) {assign(x); return *this;}
61  };
62 
63 }
64 
65 namespace classdesc
66 {
67 
68 #ifdef _CLASSDESC
69 #pragma omit xsd_generate minsky::Optional
70 #pragma omit xml_pack minsky::Optional
71 #endif
72 
73  /*
74  This code ensure optional fields are not exported when empty
75  */
76  template <class T>
77  void xsd_generate(xsd_generate_t& g, const string& d, const minsky::Optional<T>& a)
78  {
79  xsd_generate_t::Optional o(g,true);
80  T tmp; // a may be null
81  xsd_generate(g,d,tmp);
82  }
83 
84  template <class T> inline void xml_pack(xml_pack_t& t,const string& d,minsky::Optional<T>& a)
85  {if (a) ::xml_pack(t,d,*a);}
86 }
87 
90 
91 #include "optional.cd"
92 #include "optional.xcd"
93 #endif
T * operator->()
Definition: optional.h:57
static auto check(X x) -> decltype(x.empty())
reset
Definition: minsky.tcl:1325
Optional(const Optional< U > &x)
Definition: optional.h:44
void xsd_generate(xsd_generate_t &g, const string &d, const minsky::Optional< T > &a)
Definition: optional.h:77
convenience class to omit writing XML records when data absent or empty
Definition: optional.h:39
classdesc::enable_if< has_empty< U >, void >::T assign(const U &x, classdesc::dummy< 0 > d=0)
Definition: optional.h:47
Creation and access to the minskyTCL_obj object, which has code to record whenever Minsky&#39;s state cha...
Definition: constMap.h:22
const T * operator->() const
Definition: optional.h:58
void xml_pack(xml_pack_t &t, const string &d, minsky::Optional< T > &a)
Definition: optional.h:84
const T & operator*() const
Definition: optional.h:56
Optional & operator=(const U &x)
Definition: optional.h:60
static constexpr const bool value
Definition: optional.h:34
classdesc::enable_if< classdesc::Not< has_empty< U > >, void >::T assign(const U &x, classdesc::dummy< 1 > d=0)
Definition: optional.h:52
T & operator*()
Definition: optional.h:55
Optional(const T &x)
Definition: optional.h:42