Added boost header
This commit is contained in:
301
test/external/boost/serialization/smart_cast.hpp
vendored
Normal file
301
test/external/boost/serialization/smart_cast.hpp
vendored
Normal file
@@ -0,0 +1,301 @@
|
||||
#ifndef BOOST_SERIALIZATION_SMART_CAST_HPP
|
||||
#define BOOST_SERIALIZATION_SMART_CAST_HPP
|
||||
|
||||
// MS compatible compilers support #pragma once
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
|
||||
// smart_cast.hpp:
|
||||
|
||||
// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
|
||||
// Use, modification and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org/libs/serialization for updates, documentation, and revision history.
|
||||
|
||||
// casting of pointers and references.
|
||||
|
||||
// In casting between different C++ classes, there are a number of
|
||||
// rules that have to be kept in mind in deciding whether to use
|
||||
// static_cast or dynamic_cast.
|
||||
|
||||
// a) dynamic casting can only be applied when one of the types is polymorphic
|
||||
// Otherwise static_cast must be used.
|
||||
// b) only dynamic casting can do runtime error checking
|
||||
// use of static_cast is generally un checked even when compiled for debug
|
||||
// c) static_cast would be considered faster than dynamic_cast.
|
||||
|
||||
// If casting is applied to a template parameter, there is no apriori way
|
||||
// to know which of the two casting methods will be permitted or convenient.
|
||||
|
||||
// smart_cast uses C++ type_traits, and program debug mode to select the
|
||||
// most convenient cast to use.
|
||||
|
||||
#include <exception>
|
||||
#include <typeinfo>
|
||||
#include <cstddef> // NULL
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include <boost/type_traits/is_base_and_derived.hpp>
|
||||
#include <boost/type_traits/is_polymorphic.hpp>
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
#include <boost/type_traits/is_reference.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/remove_pointer.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace serialization {
|
||||
namespace smart_cast_impl {
|
||||
|
||||
template<class T>
|
||||
struct reference {
|
||||
|
||||
struct polymorphic {
|
||||
|
||||
struct linear {
|
||||
template<class U>
|
||||
static T cast(U & u){
|
||||
return static_cast< T >(u);
|
||||
}
|
||||
};
|
||||
|
||||
struct cross {
|
||||
template<class U>
|
||||
static T cast(U & u){
|
||||
return dynamic_cast< T >(u);
|
||||
}
|
||||
};
|
||||
|
||||
template<class U>
|
||||
static T cast(U & u){
|
||||
// if we're in debug mode
|
||||
#if ! defined(NDEBUG) \
|
||||
|| defined(__BORLANDC__) && (__BORLANDC__ <= 0x560) \
|
||||
|| defined(__MWERKS__)
|
||||
// do a checked dynamic cast
|
||||
return cross::cast(u);
|
||||
#else
|
||||
// borland 5.51 chokes here so we can't use it
|
||||
// note: if remove_reference isn't function for these types
|
||||
// cross casting will be selected this will work but will
|
||||
// not be the most efficient method. This will conflict with
|
||||
// the original smart_cast motivation.
|
||||
typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
|
||||
BOOST_DEDUCED_TYPENAME mpl::and_<
|
||||
mpl::not_<is_base_and_derived<
|
||||
BOOST_DEDUCED_TYPENAME remove_reference< T >::type,
|
||||
U
|
||||
> >,
|
||||
mpl::not_<is_base_and_derived<
|
||||
U,
|
||||
BOOST_DEDUCED_TYPENAME remove_reference< T >::type
|
||||
> >
|
||||
>,
|
||||
// borland chokes w/o full qualification here
|
||||
mpl::identity<cross>,
|
||||
mpl::identity<linear>
|
||||
>::type typex;
|
||||
// typex works around gcc 2.95 issue
|
||||
return typex::cast(u);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
struct non_polymorphic {
|
||||
template<class U>
|
||||
static T cast(U & u){
|
||||
return static_cast< T >(u);
|
||||
}
|
||||
};
|
||||
template<class U>
|
||||
static T cast(U & u){
|
||||
#if defined(__BORLANDC__)
|
||||
return mpl::eval_if<
|
||||
boost::is_polymorphic<U>,
|
||||
mpl::identity<polymorphic>,
|
||||
mpl::identity<non_polymorphic>
|
||||
>::type::cast(u);
|
||||
#else
|
||||
typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
|
||||
boost::is_polymorphic<U>,
|
||||
mpl::identity<polymorphic>,
|
||||
mpl::identity<non_polymorphic>
|
||||
>::type typex;
|
||||
return typex::cast(u);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct pointer {
|
||||
|
||||
struct polymorphic {
|
||||
// unfortunately, this below fails to work for virtual base
|
||||
// classes. need has_virtual_base to do this.
|
||||
// Subject for further study
|
||||
#if 0
|
||||
struct linear {
|
||||
template<class U>
|
||||
static T cast(U * u){
|
||||
return static_cast< T >(u);
|
||||
}
|
||||
};
|
||||
|
||||
struct cross {
|
||||
template<class U>
|
||||
static T cast(U * u){
|
||||
T tmp = dynamic_cast< T >(u);
|
||||
#ifndef NDEBUG
|
||||
if ( tmp == 0 ) throw std::bad_cast();
|
||||
#endif
|
||||
return tmp;
|
||||
}
|
||||
};
|
||||
|
||||
template<class U>
|
||||
static T cast(U * u){
|
||||
// if we're in debug mode
|
||||
#if ! defined(NDEBUG) || defined(__BORLANDC__) && (__BORLANDC__ <= 0x560)
|
||||
// do a checked dynamic cast
|
||||
return cross::cast(u);
|
||||
#else
|
||||
// borland 5.51 chokes here so we can't use it
|
||||
// note: if remove_pointer isn't function for these types
|
||||
// cross casting will be selected this will work but will
|
||||
// not be the most efficient method. This will conflict with
|
||||
// the original smart_cast motivation.
|
||||
typedef
|
||||
BOOST_DEDUCED_TYPENAME mpl::eval_if<
|
||||
BOOST_DEDUCED_TYPENAME mpl::and_<
|
||||
mpl::not_<is_base_and_derived<
|
||||
BOOST_DEDUCED_TYPENAME remove_pointer< T >::type,
|
||||
U
|
||||
> >,
|
||||
mpl::not_<is_base_and_derived<
|
||||
U,
|
||||
BOOST_DEDUCED_TYPENAME remove_pointer< T >::type
|
||||
> >
|
||||
>,
|
||||
// borland chokes w/o full qualification here
|
||||
mpl::identity<cross>,
|
||||
mpl::identity<linear>
|
||||
>::type typex;
|
||||
return typex::cast(u);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
template<class U>
|
||||
static T cast(U * u){
|
||||
T tmp = dynamic_cast< T >(u);
|
||||
#ifndef NDEBUG
|
||||
if ( tmp == 0 ) throw std::bad_cast();
|
||||
#endif
|
||||
return tmp;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
struct non_polymorphic {
|
||||
template<class U>
|
||||
static T cast(U * u){
|
||||
return static_cast< T >(u);
|
||||
}
|
||||
};
|
||||
|
||||
template<class U>
|
||||
static T cast(U * u){
|
||||
#if defined(__BORLANDC__)
|
||||
return mpl::eval_if<
|
||||
boost::is_polymorphic<U>,
|
||||
mpl::identity<polymorphic>,
|
||||
mpl::identity<non_polymorphic>
|
||||
>::type::cast(u);
|
||||
#else
|
||||
typedef BOOST_DEDUCED_TYPENAME mpl::eval_if<
|
||||
boost::is_polymorphic<U>,
|
||||
mpl::identity<polymorphic>,
|
||||
mpl::identity<non_polymorphic>
|
||||
>::type typex;
|
||||
return typex::cast(u);
|
||||
#endif
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<class TPtr>
|
||||
struct void_pointer {
|
||||
template<class UPtr>
|
||||
static TPtr cast(UPtr uptr){
|
||||
return static_cast<TPtr>(uptr);
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct error {
|
||||
// if we get here, its because we are using one argument in the
|
||||
// cast on a system which doesn't support partial template
|
||||
// specialization
|
||||
template<class U>
|
||||
static T cast(U u){
|
||||
BOOST_STATIC_ASSERT(sizeof(T)==0);
|
||||
return * static_cast<T *>(NULL);
|
||||
}
|
||||
};
|
||||
|
||||
} // smart_cast_impl
|
||||
|
||||
// this implements:
|
||||
// smart_cast<Target *, Source *>(Source * s)
|
||||
// smart_cast<Target &, Source &>(s)
|
||||
// note that it will fail with
|
||||
// smart_cast<Target &>(s)
|
||||
template<class T, class U>
|
||||
T smart_cast(U u) {
|
||||
typedef
|
||||
BOOST_DEDUCED_TYPENAME mpl::eval_if<
|
||||
BOOST_DEDUCED_TYPENAME mpl::or_<
|
||||
boost::is_same<void *, U>,
|
||||
boost::is_same<void *, T>,
|
||||
boost::is_same<const void *, U>,
|
||||
boost::is_same<const void *, T>
|
||||
>,
|
||||
mpl::identity<smart_cast_impl::void_pointer< T > >,
|
||||
// else
|
||||
BOOST_DEDUCED_TYPENAME mpl::eval_if<boost::is_pointer<U>,
|
||||
mpl::identity<smart_cast_impl::pointer< T > >,
|
||||
// else
|
||||
BOOST_DEDUCED_TYPENAME mpl::eval_if<boost::is_reference<U>,
|
||||
mpl::identity<smart_cast_impl::reference< T > >,
|
||||
// else
|
||||
mpl::identity<smart_cast_impl::error< T >
|
||||
>
|
||||
>
|
||||
>
|
||||
>::type typex;
|
||||
return typex::cast(u);
|
||||
}
|
||||
|
||||
// this implements:
|
||||
// smart_cast_reference<Target &>(Source & s)
|
||||
template<class T, class U>
|
||||
T smart_cast_reference(U & u) {
|
||||
return smart_cast_impl::reference< T >::cast(u);
|
||||
}
|
||||
|
||||
} // namespace serialization
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_SERIALIZATION_SMART_CAST_HPP
|
||||
Reference in New Issue
Block a user