/*=============================================================================
    Copyright (c) 2007-2010 Hartmut Kaiser
    Copyright (c) Christopher Diggins 2005
    Copyright (c) Pablo Aguilar 2005
    Copyright (c) Kevlin Henney 2001

    Distributed under 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)

    The class boost::spirit::hold_any is built based on the any class
    published here: http://www.codeproject.com/cpp/dynamic_typing.asp. It adds
    support for std streaming operator<<() and operator>>().
==============================================================================*/
#if !defined(BOOST_SPIRIT_HOLD_ANY_MAY_02_2007_0857AM)
#define BOOST_SPIRIT_HOLD_ANY_MAY_02_2007_0857AM

#if defined(_MSC_VER)
#pragma once
#endif

#include <boost/config.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/throw_exception.hpp>
#include <boost/static_assert.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/assert.hpp>
#include <boost/detail/sp_typeinfo.hpp>

#include <stdexcept>
#include <typeinfo>
#include <algorithm>
#include <iosfwd>

///////////////////////////////////////////////////////////////////////////////
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(push)
# pragma warning(disable: 4100)   // 'x': unreferenced formal parameter
# pragma warning(disable: 4127)   // conditional expression is constant
#endif

///////////////////////////////////////////////////////////////////////////////
namespace boost { namespace spirit
{
    struct bad_any_cast
      : std::bad_cast
    {
        bad_any_cast(boost::detail::sp_typeinfo const& src, boost::detail::sp_typeinfo const& dest)
          : from(src.name()), to(dest.name())
        {}

        virtual const char* what() const throw() { return "bad any cast"; }

        const char* from;
        const char* to;
    };

    namespace detail
    {
        // function pointer table
        struct fxn_ptr_table
        {
            boost::detail::sp_typeinfo const& (*get_type)();
            void (*static_delete)(void**);
            void (*destruct)(void**);
            void (*clone)(void* const*, void**);
            void (*move)(void* const*, void**);
            std::istream& (*stream_in)(std::istream&, void**);
            std::ostream& (*stream_out)(std::ostream&, void* const*);
        };

        // static functions for small value-types
        template<typename Small>
        struct fxns;

        template<>
        struct fxns<mpl::true_>
        {
            template<typename T>
            struct type
            {
                static boost::detail::sp_typeinfo const& get_type()
                {
                    return BOOST_SP_TYPEID(T);
                }
                static void static_delete(void** x)
                {
                    reinterpret_cast<T*>(x)->~T();
                }
                static void destruct(void** x)
                {
                    reinterpret_cast<T*>(x)->~T();
                }
                static void clone(void* const* src, void** dest)
                {
                    new (dest) T(*reinterpret_cast<T const*>(src));
                }
                static void move(void* const* src, void** dest)
                {
                    reinterpret_cast<T*>(dest)->~T();
                    *reinterpret_cast<T*>(dest) =
                        *reinterpret_cast<T const*>(src);
                }
                static std::istream& stream_in (std::istream& i, void** obj)
                {
                    i >> *reinterpret_cast<T*>(obj);
                    return i;
                }
                static std::ostream& stream_out(std::ostream& o, void* const* obj)
                {
                    o << *reinterpret_cast<T const*>(obj);
                    return o;
                }
            };
        };

        // static functions for big value-types (bigger than a void*)
        template<>
        struct fxns<mpl::false_>
        {
            template<typename T>
            struct type
            {
                static boost::detail::sp_typeinfo const& get_type()
                {
                    return BOOST_SP_TYPEID(T);
                }
                static void static_delete(void** x)
                {
                    // destruct and free memory
                    delete (*reinterpret_cast<T**>(x));
                }
                static void destruct(void** x)
                {
                    // destruct only, we'll reuse memory
                    (*reinterpret_cast<T**>(x))->~T();
                }
                static void clone(void* const* src, void** dest)
                {
                    *dest = new T(**reinterpret_cast<T* const*>(src));
                }
                static void move(void* const* src, void** dest)
                {
                    (*reinterpret_cast<T**>(dest))->~T();
                    **reinterpret_cast<T**>(dest) =
                        **reinterpret_cast<T* const*>(src);
                }
                static std::istream& stream_in(std::istream& i, void** obj)
                {
                    i >> **reinterpret_cast<T**>(obj);
                    return i;
                }
                static std::ostream& stream_out(std::ostream& o, void* const* obj)
                {
                    o << **reinterpret_cast<T* const*>(obj);
                    return o;
                }
            };
        };

        template<typename T>
        struct get_table
        {
            typedef mpl::bool_<(sizeof(T) <= sizeof(void*))> is_small;

            static fxn_ptr_table* get()
            {
                static fxn_ptr_table static_table =
                {
                    fxns<is_small>::template type<T>::get_type,
                    fxns<is_small>::template type<T>::static_delete,
                    fxns<is_small>::template type<T>::destruct,
                    fxns<is_small>::template type<T>::clone,
                    fxns<is_small>::template type<T>::move,
                    fxns<is_small>::template type<T>::stream_in,
                    fxns<is_small>::template type<T>::stream_out
                };
                return &static_table;
            }
        };

        ///////////////////////////////////////////////////////////////////////
        struct empty {};

        inline std::istream&
        operator>> (std::istream& i, empty&)
        {
            // If this assertion fires you tried to insert from a std istream
            // into an empty hold_any instance. This simply can't work, because
            // there is no way to figure out what type to extract from the
            // stream.
            // The only way to make this work is to assign an arbitrary
            // value of the required type to the hold_any instance you want to
            // stream to. This assignment has to be executed before the actual
            // call to the operator>>().
            BOOST_ASSERT(false);
            return i;
        }

        inline std::ostream&
        operator<< (std::ostream& o, empty const&)
        {
            return o;
        }
    }

    ///////////////////////////////////////////////////////////////////////////
    class hold_any
    {
    public:
        // constructors
        template <typename T>
        hold_any(T const& x)
          : table(spirit::detail::get_table<T>::get()), object(0)
        {
            if (spirit::detail::get_table<T>::is_small::value)
                new (&object) T(x);
            else
                object = new T(x);
        }

        hold_any()
          : table(spirit::detail::get_table<spirit::detail::empty>::get()),
            object(0)
        {
        }

        hold_any(hold_any const& x)
          : table(spirit::detail::get_table<spirit::detail::empty>::get()),
            object(0)
        {
            assign(x);
        }

        ~hold_any()
        {
            table->static_delete(&object);
        }

        // assignment
        hold_any& assign(hold_any const& x)
        {
            if (&x != this) {
                // are we copying between the same type?
                if (table == x.table) {
                    // if so, we can avoid reallocation
                    table->move(&x.object, &object);
                }
                else {
                    reset();
                    x.table->clone(&x.object, &object);
                    table = x.table;
                }
            }
            return *this;
        }

        template <typename T>
        hold_any& assign(T const& x)
        {
            // are we copying between the same type?
            spirit::detail::fxn_ptr_table* x_table =
                spirit::detail::get_table<T>::get();
            if (table == x_table) {
            // if so, we can avoid deallocating and re-use memory
                table->destruct(&object);    // first destruct the old content
                if (spirit::detail::get_table<T>::is_small::value) {
                    // create copy on-top of object pointer itself
                    new (&object) T(x);
                }
                else {
                    // create copy on-top of old version
                    new (object) T(x);
                }
            }
            else {
                if (spirit::detail::get_table<T>::is_small::value) {
                    // create copy on-top of object pointer itself
                    table->destruct(&object); // first destruct the old content
                    new (&object) T(x);
                }
                else {
                    reset();                  // first delete the old content
                    object = new T(x);
                }
                table = x_table;      // update table pointer
            }
            return *this;
        }

        // assignment operator
        template <typename T>
        hold_any& operator=(T const& x)
        {
            return assign(x);
        }

        // utility functions
        hold_any& swap(hold_any& x)
        {
            std::swap(table, x.table);
            std::swap(object, x.object);
            return *this;
        }

        boost::detail::sp_typeinfo const& type() const
        {
            return table->get_type();
        }

        template <typename T>
        T const& cast() const
        {
            if (type() != BOOST_SP_TYPEID(T))
              throw bad_any_cast(type(), BOOST_SP_TYPEID(T));

            return spirit::detail::get_table<T>::is_small::value ?
                *reinterpret_cast<T const*>(&object) :
                *reinterpret_cast<T const*>(object);
        }

// implicit casting is disabled by default for compatibility with boost::any
#ifdef BOOST_SPIRIT_ANY_IMPLICIT_CASTING
        // automatic casting operator
        template <typename T>
        operator T const& () const { return cast<T>(); }
#endif // implicit casting

        bool empty() const
        {
            return table == spirit::detail::get_table<spirit::detail::empty>::get();
        }

        void reset()
        {
            if (!empty())
            {
                table->static_delete(&object);
                table = spirit::detail::get_table<spirit::detail::empty>::get();
                object = 0;
            }
        }

    // these functions have been added in the assumption that the embedded
    // type has a corresponding operator defined, which is completely safe
    // because spirit::hold_any is used only in contexts where these operators
    // do exist
        friend std::istream& operator>> (std::istream& i, hold_any& obj)
        {
            return obj.table->stream_in(i, &obj.object);
        }

        friend std::ostream& operator<< (std::ostream& o, hold_any const& obj)
        {
            return obj.table->stream_out(o, &obj.object);
        }

#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
    private: // types
        template<typename T>
        friend T* any_cast(hold_any *);
#else
    public: // types (public so any_cast can be non-friend)
#endif
        // fields
        spirit::detail::fxn_ptr_table* table;
        void* object;
    };

    // boost::any-like casting
    template <typename T>
    inline T* any_cast (hold_any* operand)
    {
        if (operand && operand->type() == BOOST_SP_TYPEID(T)) {
            return spirit::detail::get_table<T>::is_small::value ?
                reinterpret_cast<T*>(&operand->object) :
                reinterpret_cast<T*>(operand->object);
        }
        return 0;
    }

    template <typename T>
    inline T const* any_cast(hold_any const* operand)
    {
        return any_cast<T>(const_cast<hold_any*>(operand));
    }

    template <typename T>
    T any_cast(hold_any& operand)
    {
        typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type nonref;

#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
        // If 'nonref' is still reference type, it means the user has not
        // specialized 'remove_reference'.

        // Please use BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION macro
        // to generate specialization of remove_reference for your class
        // See type traits library documentation for details
        BOOST_STATIC_ASSERT(!is_reference<nonref>::value);
#endif

        nonref* result = any_cast<nonref>(&operand);
        if(!result)
            boost::throw_exception(bad_any_cast(operand.type(), BOOST_SP_TYPEID(T)));
        return *result;
    }

    template <typename T>
    T const& any_cast(hold_any const& operand)
    {
        typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type nonref;

#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
        // The comment in the above version of 'any_cast' explains when this
        // assert is fired and what to do.
        BOOST_STATIC_ASSERT(!is_reference<nonref>::value);
#endif

        return any_cast<nonref const&>(const_cast<hold_any &>(operand));
    }

///////////////////////////////////////////////////////////////////////////////
}}    // namespace boost::spirit

///////////////////////////////////////////////////////////////////////////////
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
# pragma warning(pop)
#endif

#endif
