44 #include <type_traits>
53 virtual ~AnyHandle() {}
54 virtual const std::type_info & type()
const = 0;
55 virtual AnyHandle * clone()
const = 0;
56 virtual bool equal(AnyHandle
const *)
const = 0;
59 AnyHandle(AnyHandle
const &);
60 AnyHandle & operator=(AnyHandle
const &);
69 TypedAnyHandle(T
const & t)
73 const std::type_info & type()
const
78 AnyHandle * clone()
const
80 return new TypedAnyHandle(value_);
83 bool equal(AnyHandle
const * h)
const
85 TypedAnyHandle
const * ptr =
dynamic_cast<TypedAnyHandle
const *
>(h);
86 return ptr != 0 && value_ == ptr->value_;
90 struct ConvertibleAnyHandle
96 ConvertibleAnyHandle() {}
98 virtual signed char cast(TypeTag<signed char>)
const = 0;
99 virtual signed short cast(TypeTag<signed short>)
const = 0;
100 virtual signed int cast(TypeTag<signed int>)
const = 0;
101 virtual signed long cast(TypeTag<signed long>)
const = 0;
102 virtual signed long long cast(TypeTag<signed long long>)
const = 0;
104 virtual unsigned char cast(TypeTag<unsigned char>)
const = 0;
105 virtual unsigned short cast(TypeTag<unsigned short>)
const = 0;
106 virtual unsigned int cast(TypeTag<unsigned int>)
const = 0;
107 virtual unsigned long cast(TypeTag<unsigned long>)
const = 0;
108 virtual unsigned long long cast(TypeTag<unsigned long long>)
const = 0;
110 virtual float cast(TypeTag<float>)
const = 0;
111 virtual double cast(TypeTag<double>)
const = 0;
112 virtual long double cast(TypeTag<long double>)
const = 0;
115 #define VIGRA_ANY_OF_CONVERTIBLE(TYPE) \
117 struct TypedAnyHandle<TYPE> \
118 : public ConvertibleAnyHandle \
122 TypedAnyHandle(TYPE const & t) \
126 const std::type_info & type() const \
128 return typeid(value_); \
131 AnyHandle * clone() const \
133 return new TypedAnyHandle(value_); \
136 bool equal(AnyHandle const * h) const \
138 TypedAnyHandle const * ptr = dynamic_cast<TypedAnyHandle const *>(h); \
139 return ptr != 0 && value_ == ptr->value_; \
142 virtual signed char cast(TypeTag<signed char>) const \
143 { return static_cast<signed char>(value_); } \
144 virtual signed short cast(TypeTag<signed short>) const \
145 { return static_cast<signed short>(value_); } \
146 virtual signed int cast(TypeTag<signed int>) const \
147 { return static_cast<signed int>(value_); } \
148 virtual signed long cast(TypeTag<signed long>) const \
149 { return static_cast<signed long>(value_); } \
150 virtual signed long long cast(TypeTag<signed long long>) const \
151 { return static_cast<signed long long>(value_); } \
153 virtual unsigned char cast(TypeTag<unsigned char>) const \
154 { return static_cast<unsigned char>(value_); } \
155 virtual unsigned short cast(TypeTag<unsigned short>) const \
156 { return static_cast<unsigned short>(value_); } \
157 virtual unsigned int cast(TypeTag<unsigned int>) const \
158 { return static_cast<unsigned int>(value_); } \
159 virtual unsigned long cast(TypeTag<unsigned long>) const \
160 { return static_cast<unsigned long>(value_); } \
161 virtual unsigned long long cast(TypeTag<unsigned long long>) const \
162 { return static_cast<unsigned long long>(value_); } \
164 virtual float cast(TypeTag<float>) const \
165 { return static_cast<float>(value_); } \
166 virtual double cast(TypeTag<double>) const \
167 { return static_cast<double>(value_); } \
168 virtual long double cast(TypeTag<long double>) const \
169 { return static_cast<long double>(value_); } \
172 VIGRA_ANY_OF_CONVERTIBLE(
signed char )
173 VIGRA_ANY_OF_CONVERTIBLE(
signed short )
174 VIGRA_ANY_OF_CONVERTIBLE(
signed int )
175 VIGRA_ANY_OF_CONVERTIBLE(
signed long )
176 VIGRA_ANY_OF_CONVERTIBLE(
signed long long)
178 VIGRA_ANY_OF_CONVERTIBLE(
unsigned char )
179 VIGRA_ANY_OF_CONVERTIBLE(
unsigned short )
180 VIGRA_ANY_OF_CONVERTIBLE(
unsigned int )
181 VIGRA_ANY_OF_CONVERTIBLE(
unsigned long )
182 VIGRA_ANY_OF_CONVERTIBLE(
unsigned long long)
184 VIGRA_ANY_OF_CONVERTIBLE(
float )
185 VIGRA_ANY_OF_CONVERTIBLE(
double )
186 VIGRA_ANY_OF_CONVERTIBLE(
long double)
188 #undef VIGRA_ANY_OF_CONVERTIBLE
233 VIGRA_UNIQUE_PTR<detail::AnyHandle> handle_;
240 : handle_((detail::AnyHandle*)0)
247 : handle_(new detail::TypedAnyHandle<T>(t))
253 : handle_(bool(other) ? other.handle_->clone() : (detail::AnyHandle*)0)
262 handle_.reset(
new detail::TypedAnyHandle<T>(t));
272 handle_.reset(
bool(other) ? other.handle_->clone() : (detail::AnyHandle*)0);
280 handle_.reset((detail::AnyHandle*)0);
287 #ifdef VIGRA_NO_UNIQUE_PTR // fallback for old compilers
288 detail::AnyHandle *t = handle_.release(),
289 *o = other.handle_.release();
291 other.handle_.reset(t);
293 handle_.swap(other.handle_);
309 return (handle_.get() == 0 && other.handle_.get() == 0) ||
310 (handle_.get() != 0 && handle_->equal(other.handle_.get()));
322 return bool(*
this) == other;
327 return bool(*
this) != other;
332 operator bool()
const
334 return handle_.get() != 0;
341 return handle_.get() == 0;
349 return dynamic_cast<detail::TypedAnyHandle<T>
const *
>(handle_.get()) != 0;
359 return (
dynamic_cast<detail::TypedAnyHandle<T>
const *
>(handle_.get()) != 0) ||
360 (std::is_arithmetic<T>::value &&
361 dynamic_cast<detail::ConvertibleAnyHandle
const *
>(handle_.get()) != 0);
370 vigra_precondition(
bool(*
this),
"Any::get(): object empty.");
371 auto ptr =
dynamic_cast<detail::TypedAnyHandle<T> *
>(handle_.get());
372 vigra_precondition(ptr != 0,
"Any::get(): object is not an instance of the target type.");
380 T
const &
get()
const
382 vigra_precondition(
bool(*
this),
"Any::get(): object empty.");
383 auto ptr =
dynamic_cast<detail::TypedAnyHandle<T>
const *
>(handle_.get());
384 vigra_precondition(ptr != 0,
"Any::get(): object is not an instance of the target type.");
395 vigra_precondition(
bool(*
this),
"Any::read(): object empty.");
396 auto ptr1 =
dynamic_cast<detail::TypedAnyHandle<T>
const *
>(handle_.get());
399 auto ptr2 =
dynamic_cast<detail::ConvertibleAnyHandle
const *
>(handle_.get());
400 vigra_precondition(ptr2 != 0,
"Any::read(): object is not covertible to the target type.");
401 return ptr2->cast(detail::ConvertibleAnyHandle::TypeTag<T>());
407 #endif // VIGRA_ANY_HXX
bool operator==(Any const &other) const
Definition: any.hxx:307
Any & operator=(T const &t)
Definition: any.hxx:260
bool operator!=(Any const &other) const
Definition: any.hxx:315
bool is_type() const
Definition: any.hxx:347
Any(Any const &other)
Definition: any.hxx:252
friend void swap(Any &l, Any &r)
Definition: any.hxx:299
Any()
Definition: any.hxx:239
Any(T const &t)
Definition: any.hxx:246
T read() const
Definition: any.hxx:393
Typesafe storage of arbitrary values.
Definition: any.hxx:230
void destroy()
Definition: any.hxx:278
bool empty() const
Definition: any.hxx:339
void swap(Any &other)
Definition: any.hxx:285
Any & operator=(Any const &other)
Definition: any.hxx:269
bool is_readable() const
Definition: any.hxx:357