iutest  1.17.99.14
iutest_any.hpp
[詳解]
1 //======================================================================
2 //-----------------------------------------------------------------------
13 //-----------------------------------------------------------------------
14 //======================================================================
15 #ifndef INCG_IRIS_IUTEST_ANY_HPP_8DB2417F_568A_4E01_95AD_21164565B975_
16 #define INCG_IRIS_IUTEST_ANY_HPP_8DB2417F_568A_4E01_95AD_21164565B975_
17 
18 //======================================================================
19 // include
20 // IWYU pragma: begin_exports
22 // IWYU pragma: end_exports
23 
24 //======================================================================
25 // class
26 namespace iutest
27 {
28 
32 class any
33 {
34  typedef internal::TypeId type_id;
35 public:
36  any() : content(NULL) {}
37  template<typename T>
38  any(const T& rhs) : content(new holder<T>(rhs)) {} // NOLINT
39  any(const any& rhs) : content(rhs.content == NULL ? NULL : rhs.content->clone()) {}
40  any(const char rhs[]) : content(new holder< ::std::string >(::std::string(rhs)) ) {} // NOLINT
41  ~any() { delete content; }
42 public:
46  any& swap(any& rhs)
47  {
48  ::std::swap(content, rhs.content);
49  return *this;
50  }
55  bool empty() const
56  {
57  return content == NULL;
58  }
62  void clear()
63  {
64  any().swap(*this);
65  }
70  type_id type() const
71  {
72  return content == NULL ? internal::GetTypeId<void>() : content->type();
73  }
78  template<typename T>
79  bool type_equal() const
80  {
81  return type() == internal::GetTypeId<T>();
82  }
83 
87  ::std::string to_string() const
88  {
89  if(empty())
90  {
91  return "empty";
92  }
93  return content->to_string();
94  }
95 
96 public:
100  bool has_value() const
101  {
102  return !empty();
103  }
107  void reset()
108  {
109  clear();
110  }
111 
112 public:
113  template<typename T>
114  any& operator = (const T& rhs) { any(rhs).swap(*this); return *this; }
115  any& operator = (const any& rhs) { any(rhs).swap(*this); return *this; }
116 
117  template<typename T>
118  friend T* any_cast(any*);
119  template<typename T>
120  friend T* unsafe_any_cast(any*);
121 
122 private:
123  class placeholder
124  {
125  public:
126  virtual ~placeholder() {}
127  virtual type_id type() const = 0;
128  virtual placeholder* clone() const = 0;
129  virtual ::std::string to_string() const = 0;
130  };
131  template<typename T>
132  class holder IUTEST_CXX_FINAL : public placeholder
133  {
134  public:
135  explicit holder(const T& v) : held(v) {}
136  public:
137  virtual type_id type() const IUTEST_CXX_OVERRIDE
138  {
139  return internal::GetTypeId<T>();
140  }
141  virtual placeholder* clone() const IUTEST_CXX_OVERRIDE
142  {
143  return new holder<T>(held);
144  }
145  virtual ::std::string to_string() const IUTEST_CXX_OVERRIDE
146  {
147  return PrintToString(held);
148  }
149  public:
150  T held;
151  private:
152  holder& operator = (const holder&);
153  };
154 private:
155  placeholder* content;
156 };
157 
158 #if IUTEST_HAS_EXCEPTIONS
162 class bad_any_cast : public ::std::bad_cast {};
163 #endif
164 
165 inline void swap(any& lhs, any& rhs) { lhs.swap(rhs); }
166 
170 template<typename T>
171 T* any_cast(any* p)
172 {
173  return p != NULL && p->type_equal<T>() ?
174  &(static_cast< any::holder<T>* >(p->content)->held) : NULL;
175 }
177 template<typename T>
178 inline const T* any_cast(const any* p)
179 {
180  return any_cast<T>(const_cast<any*>(p));
181 }
183 template<typename T>
184 inline T any_cast(any& value)
185 {
186 #if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
187  typedef typename type_traits::remove_reference<T>::type nonref_t;
188 #else
189  typedef T nonref_t;
190 #endif
191  nonref_t* p = any_cast<nonref_t>(&value);
192 #if IUTEST_HAS_EXCEPTIONS
193  if( p == NULL ) {
194  throw bad_any_cast();
195  }
196 #endif
197 
198  return static_cast<nonref_t&>(*p);
199 }
201 template<typename T>
202 inline T any_cast(const any& value)
203 {
204  return any_cast<T>(const_cast<any&>(value));
205 }
206 
210 template<typename T>
211 T* unsafe_any_cast(any* p)
212 {
213  if(p == NULL)
214  {
215  return NULL;
216  }
217  if(!p->has_value())
218  {
219  return NULL;
220  }
221  return &(static_cast< any::holder<T>* >(p->content)->held);
222 }
224 template<typename T>
225 inline const T* unsafe_any_cast(const any* p)
226 {
227  return unsafe_any_cast<T>(const_cast<any*>(p));
228 }
230 template<typename T>
231 inline T unsafe_any_cast(any& value)
232 {
233 #if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
234  typedef typename type_traits::remove_reference<T>::type nonref_t;
235 #else
236  typedef T nonref_t;
237 #endif
238  nonref_t* p = unsafe_any_cast<nonref_t>(&value);
239  return static_cast<nonref_t&>(*p);
240 }
242 template<typename T>
243 inline T unsafe_any_cast(const any& value)
244 {
245  return unsafe_any_cast<T>(const_cast<any&>(value));
246 }
247 
248 #if !defined(IUTEST_NO_ARGUMENT_DEPENDENT_LOOKUP)
249 
250 #if IUTEST_HAS_STRINGSTREAM || IUTEST_HAS_STRSTREAM
251 template<typename Elem, typename Traits>
252 inline ::std::basic_ostream<Elem, Traits>& operator << (::std::basic_ostream<Elem, Traits>& os, const any& value)
253 {
254  return os << value.to_string();
255 }
256 #else
257 inline iu_ostream& operator << (iu_ostream& os, const any& value)
258 {
259  return os << value.to_string();
260 }
261 #endif
262 
263 #endif
264 
265 } // end of namespace iutest
266 
267 #endif // INCG_IRIS_IUTEST_ANY_HPP_8DB2417F_568A_4E01_95AD_21164565B975_
any
Definition: iutest_any.hpp:34
bool has_value() const
要素があるかどうか
Definition: iutest_any.hpp:101
bool empty() const
空かどうか
Definition: iutest_any.hpp:56
type_id type() const
型IDの取得
Definition: iutest_any.hpp:71
any & swap(any &rhs)
swap
Definition: iutest_any.hpp:47
::std::string to_string() const
所持している値の文字列化
Definition: iutest_any.hpp:88
void reset()
要素のクリア
Definition: iutest_any.hpp:108
bool type_equal() const
型の比較
Definition: iutest_any.hpp:80
void clear()
要素のクリア
Definition: iutest_any.hpp:63
friend T * unsafe_any_cast(any *)
型を考慮せずキャスト
Definition: iutest_any.hpp:212
friend T * any_cast(any *)
型を考慮したキャスト
Definition: iutest_any.hpp:172
any_cast の失敗例外
Definition: iutest_any.hpp:163
#define IUTEST_CXX_FINAL
final definition
Definition: iutest_compiler.hpp:756
#define IUTEST_CXX_OVERRIDE
override definition
Definition: iutest_compiler.hpp:747
internal definition
iutest root namespace
Definition: iutest_charcode.hpp:33
std::string PrintToString(const T &v)
文字列化
Definition: iutest_printers.hpp:767
T * any_cast(any *p)
型を考慮したキャスト
Definition: iutest_any.hpp:172
T * unsafe_any_cast(any *p)
型を考慮せずキャスト
Definition: iutest_any.hpp:212