iutest  1.17.1.0
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
21 
22 //======================================================================
23 // class
24 namespace iutest
25 {
26 
30 class any
31 {
32  typedef internal::TypeId type_id;
33 public:
34  any() : content(NULL) {}
35  template<typename T>
36  any(const T& rhs) : content(new holder<T>(rhs)) {} // NOLINT
37  any(const any& rhs) : content(rhs.content == NULL ? NULL : rhs.content->clone()) {}
38  any(const char rhs[]) : content(new holder< ::std::string >(::std::string(rhs)) ) {} // NOLINT
39  ~any() { delete content; }
40 public:
44  any& swap(any& rhs)
45  {
46  ::std::swap(content, rhs.content);
47  return *this;
48  }
53  bool empty() const
54  {
55  return content == NULL;
56  }
60  void clear()
61  {
62  any().swap(*this);
63  }
68  type_id type() const
69  {
70  return content == NULL ? internal::GetTypeId<void>() : content->type();
71  }
76  template<typename T>
77  bool type_equal() const
78  {
79  return type() == internal::GetTypeId<T>();
80  }
81 
85  ::std::string to_string() const
86  {
87  if(empty())
88  {
89  return "empty";
90  }
91  return content->to_string();
92  }
93 
94 public:
98  bool has_value() const
99  {
100  return !empty();
101  }
105  void reset()
106  {
107  clear();
108  }
109 
110 public:
111  template<typename T>
112  any& operator = (const T& rhs) { any(rhs).swap(*this); return *this; }
113  any& operator = (const any& rhs) { any(rhs).swap(*this); return *this; }
114 
115  template<typename T>
116  friend T* any_cast(any*);
117  template<typename T>
118  friend T* unsafe_any_cast(any*);
119 
120 private:
121  class placeholder
122  {
123  public:
124  virtual ~placeholder() {}
125  virtual type_id type() const = 0;
126  virtual placeholder* clone() const = 0;
127  virtual ::std::string to_string() const = 0;
128  };
129  template<typename T>
130  class holder : public placeholder
131  {
132  public:
133  explicit holder(const T& v) : held(v) {}
134  public:
135  virtual type_id type() const IUTEST_CXX_OVERRIDE
136  {
137  return internal::GetTypeId<T>();
138  }
139  virtual placeholder* clone() const IUTEST_CXX_OVERRIDE
140  {
141  return new holder<T>(held);
142  }
143  virtual ::std::string to_string() const IUTEST_CXX_OVERRIDE
144  {
145  return PrintToString(held);
146  }
147  public:
148  T held;
149  private:
150  holder& operator = (const holder&);
151  };
152 private:
153  placeholder* content;
154 };
155 
156 #if IUTEST_HAS_EXCEPTIONS
157 
160 class bad_any_cast : public ::std::bad_cast {};
161 #endif
162 
163 inline void swap(any& lhs, any& rhs) { lhs.swap(rhs); }
164 
168 template<typename T>
169 T* any_cast(any* p)
170 {
171  return p != NULL && p->type_equal<T>() ?
172  &(static_cast< any::holder<T>* >(p->content)->held) : NULL;
173 }
175 template<typename T>
176 inline const T* any_cast(const any* p)
177 {
178  return any_cast<T>(const_cast<any*>(p));
179 }
181 template<typename T>
182 inline T any_cast(any& value)
183 {
184 #if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
185  typedef typename type_traits::remove_reference<T>::type nonref_t;
186 #else
187  typedef T nonref_t;
188 #endif
189  nonref_t* p = any_cast<nonref_t>(&value);
190 #if IUTEST_HAS_EXCEPTIONS
191  if( p == NULL ) {
192  throw bad_any_cast();
193  }
194 #endif
195 
196  return static_cast<nonref_t&>(*p);
197 }
199 template<typename T>
200 inline T any_cast(const any& value)
201 {
202  return any_cast<T>(const_cast<any&>(value));
203 }
204 
208 template<typename T>
209 T* unsafe_any_cast(any* p)
210 {
211  if(p == NULL)
212  {
213  return NULL;
214  }
215  if(!p->has_value())
216  {
217  return NULL;
218  }
219  return &(static_cast< any::holder<T>* >(p->content)->held);
220 }
222 template<typename T>
223 inline const T* unsafe_any_cast(const any* p)
224 {
225  return unsafe_any_cast<T>(const_cast<any*>(p));
226 }
228 template<typename T>
229 inline T unsafe_any_cast(any& value)
230 {
231 #if !defined(IUTEST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
232  typedef typename type_traits::remove_reference<T>::type nonref_t;
233 #else
234  typedef T nonref_t;
235 #endif
236  nonref_t* p = unsafe_any_cast<nonref_t>(&value);
237  return static_cast<nonref_t&>(*p);
238 }
240 template<typename T>
241 inline T unsafe_any_cast(const any& value)
242 {
243  return unsafe_any_cast<T>(const_cast<any&>(value));
244 }
245 
246 #if !defined(IUTEST_NO_ARGUMENT_DEPENDENT_LOOKUP)
247 
248 #if IUTEST_HAS_STRINGSTREAM || IUTEST_HAS_STRSTREAM
249 template<typename Elem, typename Traits>
250 inline ::std::basic_ostream<Elem, Traits>& operator << (::std::basic_ostream<Elem, Traits>& os, const any& value)
251 {
252  return os << value.to_string();
253 }
254 #else
255 inline iu_ostream& operator << (iu_ostream& os, const any& value)
256 {
257  return os << value.to_string();
258 }
259 #endif
260 
261 #endif
262 
263 } // end of namespace iutest
264 
265 #endif // INCG_IRIS_IUTEST_ANY_HPP_8DB2417F_568A_4E01_95AD_21164565B975_
iutest::any::type_equal
bool type_equal() const
型の比較
Definition: iutest_any.hpp:78
iutest::any::empty
bool empty() const
空かどうか
Definition: iutest_any.hpp:54
iutest::any::has_value
bool has_value() const
要素があるかどうか
Definition: iutest_any.hpp:99
iutest::any
any
Definition: iutest_any.hpp:31
iutest_internal_defs.hpp
internal definition
iutest_config.hpp
iris unit test config
iutest::any::any_cast
friend T * any_cast(any *)
型を考慮したキャスト
Definition: iutest_any.hpp:170
iutest::PrintToString
std::string PrintToString(const T &v)
文字列化
Definition: iutest_printers.hpp:678
iutest
iutest root namespace
Definition: iutest_charcode.hpp:31
iutest::any::clear
void clear()
要素のクリア
Definition: iutest_any.hpp:61
IUTEST_CXX_OVERRIDE
#define IUTEST_CXX_OVERRIDE
override definition
Definition: iutest_compiler.hpp:670
iutest::any::type
type_id type() const
型IDの取得
Definition: iutest_any.hpp:69
iutest::any::reset
void reset()
要素のクリア
Definition: iutest_any.hpp:106
iutest::any::swap
any & swap(any &rhs)
swap
Definition: iutest_any.hpp:45
iutest::bad_any_cast
any_cast の失敗例外
Definition: iutest_any.hpp:161
iutest::any_cast
T * any_cast(any *p)
型を考慮したキャスト
Definition: iutest_any.hpp:170
iutest::any::unsafe_any_cast
friend T * unsafe_any_cast(any *)
型を考慮せずキャスト
Definition: iutest_any.hpp:210
iutest::any::to_string
::std::string to_string() const
所持している値の文字列化
Definition: iutest_any.hpp:86
iutest::unsafe_any_cast
T * unsafe_any_cast(any *p)
型を考慮せずキャスト
Definition: iutest_any.hpp:210