Commit 30e8807f authored by Davis King's avatar Davis King

Added an any container object.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%403942
parent 47e81212
// Copyright (C) 2010 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_AnY_
#define DLIB_AnY_
#include "any/any.h"
#endif // DLIB_AnY_
// Copyright (C) 2010 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_AnY_H_
#define DLIB_AnY_H_
#include "any_abstract.h"
#include "../smart_pointers.h"
#include <typeinfo>
namespace dlib
{
// ----------------------------------------------------------------------------------------
class bad_any_cast : public std::bad_cast
{
public:
virtual const char * what() const throw()
{
return "bad_any_cast";
}
};
// ----------------------------------------------------------------------------------------
class any
{
template <typename T> struct basic_type { typedef T type; };
template <typename T> struct basic_type<const T> { typedef T type; };
template <typename T> struct basic_type<const T&> { typedef T type; };
template <typename T> struct basic_type<volatile const T&> { typedef T type; };
template <typename T> struct basic_type<T&> { typedef T type; };
template <typename T> struct basic_type<volatile T&> { typedef T type; };
template <typename T> struct basic_type<volatile T> { typedef T type; };
template <typename T> struct basic_type<volatile const T> { typedef T type; };
public:
any()
{
}
any (
const any& item
)
{
if (item.data)
{
item.data->copy_to(data);
}
}
template <typename T>
any (
const T& item
)
{
typedef typename basic_type<T>::type U;
data.reset(new derived<U>(item));
}
void clear (
)
{
data.reset();
}
template <typename T>
bool contains (
) const
{
typedef typename basic_type<T>::type U;
return dynamic_cast<derived<U>*>(data.get()) != 0;
}
bool is_empty(
) const
{
return data.get() == 0;
}
template <typename T>
T& cast_to(
)
{
typedef typename basic_type<T>::type U;
derived<U>* d = dynamic_cast<derived<U>*>(data.get());
if (d == 0)
{
throw bad_any_cast();
}
return d->item;
}
template <typename T>
const T& cast_to(
) const
{
typedef typename basic_type<T>::type U;
derived<U>* d = dynamic_cast<derived<U>*>(data.get());
if (d == 0)
{
throw bad_any_cast();
}
return d->item;
}
template <typename T>
T& get(
)
{
typedef typename basic_type<T>::type U;
derived<U>* d = dynamic_cast<derived<U>*>(data.get());
if (d == 0)
{
d = new derived<U>();
data.reset(d);
}
return d->item;
}
any& operator= (
const any& item
)
{
any(item).swap(*this);
return *this;
}
void swap (
any& item
)
{
data.swap(item.data);
}
private:
struct base
{
virtual ~base() {}
virtual void copy_to (
scoped_ptr<base>& dest
) const = 0;
};
template <typename T>
struct derived : public base
{
T item;
derived() {}
derived(const T& val) : item(val) {}
virtual void copy_to (
scoped_ptr<base>& dest
) const
{
dest.reset(new derived<T>(item));
}
};
scoped_ptr<base> data;
};
// ----------------------------------------------------------------------------------------
inline void swap (
any& a,
any& b
) { a.swap(b); }
// ----------------------------------------------------------------------------------------
template <typename T> T& any_cast(any& a) { return a.cast_to<T>(); }
template <typename T> const T& any_cast(const any& a) { return a.cast_to<T>(); }
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_AnY_H_
// Copyright (C) 2010 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#undef DLIB_AnY_ABSTRACT_H_
#ifdef DLIB_AnY_ABSTRACT_H_
#include <typeinfo>
namespace dlib
{
// ----------------------------------------------------------------------------------------
class bad_any_cast : public std::bad_cast
{
/*!
WHAT THIS OBJECT REPRESENTS
This object is the exception class used by the any object.
It is used to indicate when someone attempts to cast an any
object into a type which isn't contained in the any object.
!*/
public:
virtual const char* what() const throw() { return "bad_any_cast"; }
};
// ----------------------------------------------------------------------------------------
class any
{
/*!
INITIAL VALUE
- is_empty() == true
- for all T: contains<T>() == false
WHAT THIS OBJECT REPRESENTS
This object is basically a type-safe version of a void*. In particular,
it is a container which can contain only one object but the object may
be of any type.
It is somewhat like the type_safe_union except you don't have to declare
the set of possible content types beforehand. So in some sense this is
like a less type-strict version of the type_safe_union.
!*/
public:
any(
);
/*!
ensures
- this object is properly initialized
!*/
any (
const any& item
);
/*!
ensures
- copies the state of item into *this.
- Note that *this and item will contain independent copies of the
contents of item. That is, this function performs a deep
copy and therefore does not result in *this containing
any kind of reference to item.
!*/
template < typename T >
any (
const T& item
);
/*!
ensures
- #contains<T>() == true
- #cast_to<T>() == item
(i.e. a copy of item will be stored in *this)
!*/
void clear (
);
/*!
ensures
- #*this will have its default value. I.e. #is_empty() == true
!*/
template <typename T>
bool contains (
) const;
/*!
ensures
- if (this object currently contains an object of type T) then
- returns true
- else
- returns false
!*/
bool is_empty(
) const;
/*!
ensures
- if (this object contains any kind of object) then
- returns true
- else
- returns false
!*/
template <typename T>
T& cast_to(
);
/*!
ensures
- if (contains<T>() == true) then
- returns a non-const reference to the object contained within *this
- else
- throws bad_any_cast
!*/
template <typename T>
const T& cast_to(
) const;
/*!
ensures
- if (contains<T>() == true) then
- returns a const reference to the object contained within *this
- else
- throws bad_any_cast
!*/
template <typename T>
T& get(
);
/*!
ensures
- #is_empty() == false
- #contains<T>() == true
- if (contains<T>() == true)
- returns a non-const reference to the object contained in *this.
- else
- Constructs an object of type T inside *this
- Any previous object stored in this any object is destructed and its
state is lost.
- returns a non-const reference to the newly created T object.
!*/
any& operator= (
const any& item
);
/*!
ensures
- copies the state of item into *this.
- Note that *this and item will contain independent copies of the
contents of item. That is, this function performs a deep
copy and therefore does not result in *this containing
any kind of reference to item.
!*/
void swap (
any& item
);
/*!
ensures
- swaps *this and item
!*/
};
// ----------------------------------------------------------------------------------------
inline void swap (
any& a,
any& b
) { a.swap(b); }
/*!
provides a global swap function
!*/
// ----------------------------------------------------------------------------------------
template <
typename T
>
T& any_cast(
any& a
) { return a.cast_to<T>(); }
/*!
ensures
- returns a.cast_to<T>()
!*/
// ----------------------------------------------------------------------------------------
template <
typename T
>
const T& any_cast(
const any& a
) { return a.cast_to<T>(); }
/*!
ensures
- returns a.cast_to<T>()
!*/
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_AnY_ABSTRACT_H_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment