Any.hpp
1 #pragma once
2 
3 #include "DM/config.hpp"
4 #include "DM/AutoLink.hpp" //enable autolink
5 #include "DM/Exception.hpp"
6 
7 #include <typeindex>
8 #include <type_traits>
9 
10 DM_NAMESPACE_BEGIN
11 
12  /**
13  \class Any
14 
15  \author jo
16  \date 27.01.2012
17 
18  Any can store any object without sacrificing type safety. Class is strongly based on boost::any except
19  that the type() member function doesn't return a const std::type_index & (but a copy std::type_index)
20  */
21 
22  class DM_API Any
23  {
24  public: // structors
25  Any() noexcept: content(0) {
26  }
27 
28  template<typename ValueType>
29  Any(const ValueType & value) : content(new holder<
30  typename std::remove_cv<typename std::decay<const ValueType>::type>::type
31  >(value)) {
32  }
33 
34  Any(const Any & other) : content(other.content ? other.content->clone() : 0) {
35  }
36 
37  // Move constructor
38  Any(Any&& other) noexcept : content(other.content) {
39  other.content = 0;
40  }
41 
42  // Perfect forwarding of ValueType
43  template<typename ValueType>
44  Any(ValueType&& value
45  , typename std::enable_if< !std::is_same<Any&, ValueType>::value >::type* = 0 // disable if value has type `any&`
46  , typename std::enable_if< !std::is_const<ValueType>::value >::type* = 0) // disable if value has type `const ValueType&&`
47  : content(new holder< typename std::decay<ValueType>::type >(static_cast<ValueType&&>(value)))
48  {
49  }
50 
51  ~Any() noexcept {
52  delete content;
53  }
54 
55  public: // modifiers
56  Any & swap(Any & rhs) noexcept {
57  std::swap(content, rhs.content);
58  return *this;
59  }
60 
61  Any & operator=(const Any& rhs) {
62  Any(rhs).swap(*this);
63  return *this;
64  }
65 
66  // move assignement
67  Any & operator=(Any&& rhs) noexcept
68  {
69  rhs.swap(*this);
70  Any().swap(rhs);
71  return *this;
72  }
73 
74  // Perfect forwarding of ValueType
75  template <class ValueType>
76  Any & operator=(ValueType&& rhs)
77  {
78  Any(static_cast<ValueType&&>(rhs)).swap(*this);
79  return *this;
80  }
81 
82  public: // queries
83  bool empty() const noexcept {
84  return !content;
85  }
86  void clear() noexcept {
87  Any().swap(*this);
88  }
89  std::type_index type() const noexcept {
90  return content ? content->type() : std::type_index(typeid(void));
91  }
92 
93  private: // types
94 
95  class placeholder
96  {
97  public: // structors
98  virtual ~placeholder() { }
99 
100  public: // queries
101  virtual std::type_index type() const noexcept = 0;
102  virtual placeholder * clone() const = 0;
103  };
104 
105  template<typename ValueType>
106  class holder : public placeholder
107  {
108  public: // structors
109  holder(const ValueType & value) : held(value) { }
110  holder(ValueType&& value) : held(static_cast< ValueType&& >(value)) { }
111 
112  public: // queries
113  virtual std::type_index type() const noexcept {
114  return std::type_index(typeid(ValueType));
115  }
116  virtual placeholder * clone() const {
117  return new holder(held);
118  }
119 
120  public: // representation
121  ValueType held;
122 
123  private: // intentionally left unimplemented
124  holder & operator=(const holder &);
125  };
126 
127  private: // representation
128 
129  template<typename ValueType>
130  friend ValueType * any_cast(Any *) noexcept;
131  template<typename ValueType>
132  friend ValueType * unsafe_any_cast(Any *) noexcept;
133 
134  placeholder * content;
135  };
136 
137  inline void swap(Any & lhs, Any & rhs) noexcept { lhs.swap(rhs); }
138 
139  class DM_API BadAnyCast : public NG_exception
140  {
141  public:
142  virtual const char * what() const noexcept{
143  return "boost::bad_any_cast: failed conversion using boost::any_cast";
144  }
145  };
146 
147  template<typename ValueType>
148  ValueType * any_cast(Any * operand) noexcept
149  {
150  return operand && operand->type() == std::type_index(typeid(ValueType))
151  ? std::addressof(
152  static_cast<Any::holder<typename std::remove_cv<ValueType>::type> *>(operand->content)->held
153  )
154  : 0;
155  }
156 
157  template<typename ValueType>
158  inline const ValueType * any_cast(const Any * operand) noexcept
159  {
160  return any_cast<ValueType>(const_cast<Any *>(operand));
161  }
162 
163  template<typename ValueType>
164  ValueType any_cast(Any & operand)
165  {
166  typedef typename std::remove_reference<ValueType>::type nonref;
167 
168  nonref * result = any_cast<nonref>(std::addressof(operand));
169  if(!result)
170  throw BadAnyCast();
171 
172  // Attempt to avoid construction of a temporary object in cases when
173  // `ValueType` is not a reference. Example:
174  // `static_cast<std::string>(*result);`
175  // which is equal to `std::string(*result);`
176  typedef typename std::conditional <
177  std::is_reference<ValueType>::value ,
178  ValueType,
179  typename std::add_lvalue_reference<ValueType>::type
180  >::type ref_type;
181 
182 #ifdef _MSC_VER
183 # pragma warning(push)
184 # pragma warning(disable: 4172) // "returning address of local variable or temporary" but *result is not local!
185 #endif
186  return static_cast<ref_type>(*result);
187 #ifdef _MSC_VER
188 # pragma warning(pop)
189 #endif
190  }
191 
192  template<typename ValueType>
193  inline ValueType any_cast(const Any & operand)
194  {
195  typedef typename std::remove_reference<ValueType>::type nonref;
196  return any_cast<const nonref &>(const_cast<Any &>(operand));
197  }
198 
199 
200 DM_NAMESPACE_END
def fprjdir(prjdir)
analyzes input parameter and returns filelist, pairs
Definition: analyzeInput.py:166
kernel
Definition: analyzeDEM.py:97
Definition: Any.hpp:22
def ftemp(temp, prjdir, outdir, scriptname)
analyzes temp parameter and returns tempdir
Definition: analyzeInput.py:339
def fcfgP(cfg, prjdir, allscripts, scriptname, fullscriptpath)
"analyzes cfg parameter and returns the cfgs for each subscript
Definition: analyzeInput.py:447
def fsettingsP(txtfile, prjdir, allscripts)
reads settings-textfile and returns the settings for each subscript
Definition: analyzeInput.py:373
def analyzeInput(fullscriptpath, pairboolean, inp=None, out=None, temp=None, cfg=None, prjdir=None, gearman=None, skipIfExists=None)
analyzes the parser arguments (inp, out, temp, cfg, prjdir, gearman) and returns script parameters (f...
Definition: analyzeInput.py:82
thrown if the provided filename doesn't exist.
Definition: c++_api/inc/opals/Exception.hpp:238
delete
Definition: analyzeDEM.py:105
vis
Definition: analyzeDEM.py:101
dir
Definition: analyzeDEM.py:99
Processing opals jobs via gearman in the cloud.
Definition: processor.py:111
Exception wrapper.
Definition: NG_Exception.hpp:13
poly
Definition: analyzeDEM.py:91
def standardinput(inp)
analyzes non-textfile inputs including wildcards; returns filelist
Definition: analyzeInput.py:300
hist
Definition: analyzeDEM.py:103
list attrs
Definition: analyzeDEM.py:76
programming error which appears if the opals framework wasn't used correctly;
Definition: c++_api/inc/opals/Exception.hpp:200
def foutP(out, temp, prjdir, allscripts, scriptname)
analyzes out parameter and returns the outdirs for each subscript
Definition: analyzeInput.py:403
def fcfg(cfg, prjdir, scriptname, fullscriptpath)
analyzes cfg parameter and returns the path of the cfg-file
Definition: analyzeInput.py:353
def finp(inp, prjdir, supportFilter=False)
analyzes the input parameters and returns filelist, pairs
Definition: analyzeInput.py:182
Process opals jobs on the local machine.
Definition: processor.py:15
def analyzeInputPackages(fullscriptpath, pairboolean, allscripts, inp=None, out=None, temp=None, cfg=None, prjdir=None, gearman=None, subScriptList=None, subScriptString=None, skipIfExists=None)
analyzes the parser arguments (inp, out, temp, cfg) and returns script parameters (filelist,...
Definition: analyzeInput.py:118
Definition: analyzeInput.py:25
terrainModel
Definition: analyzeDEM.py:81
def fout(out, prjdir, scriptname)
analyzes out parameter and returns outdir
Definition: analyzeInput.py:325
def textfileinput(inp, filedir, supportFilter)
reads textfile and returns filelist, pairs
Definition: analyzeInput.py:223
size
Definition: analyzeDEM.py:95
def findfile(f, fdir)
"searches filedir for a certain strip file or odm file, returns boolean
Definition: analyzeInput.py:286
def argumentSplit(obj, separator=';', old_type=str)
splitting a string or a list of strings by a given separator into a list
Definition: analyzeInput.py:55
rounding
Definition: analyzeDEM.py:93
Definition: Any.hpp:139
def ftempP(temp, prjdir, outdirs, allscripts, scriptname)
analyzes temp parameter and returns the tempdirs for each subscript
Definition: analyzeInput.py:435
surfaceModel
Definition: analyzeDEM.py:83
zone
Definition: analyzeDEM.py:85
list readonly_attrs
Definition: analyzeDEM.py:77
border
Definition: analyzeDEM.py:89
class for packages.python.analyzeDEM
Definition: analyzeDEM.py:75
skip
Definition: analyzeDEM.py:107
att
Definition: analyzeDEM.py:87