#ifndef MAPBOX_UTIL_VARIANT_HPP
#define MAPBOX_UTIL_VARIANT_HPP

#include <cassert>
#include <cstddef>   // size_t
#include <new>       // operator new
#include <stdexcept> // runtime_error
#include <string>
#include <tuple>
#include <type_traits>
#include <typeinfo>
#include <utility>

#include <mapbox/recursive_wrapper.hpp>

// clang-format off
// [[deprecated]] is only available in C++14, use this for the time being
#if __cplusplus <= 201103L
# ifdef __GNUC__
#  define MAPBOX_VARIANT_DEPRECATED __attribute__((deprecated))
# elif defined(_MSC_VER)
#  define MAPBOX_VARIANT_DEPRECATED __declspec(deprecated)
# else
#  define MAPBOX_VARIANT_DEPRECATED
# endif
#else
#  define MAPBOX_VARIANT_DEPRECATED [[deprecated]]
#endif


#ifdef _MSC_VER
// https://msdn.microsoft.com/en-us/library/bw1hbe6y.aspx
# ifdef NDEBUG
#  define VARIANT_INLINE __forceinline
# else
#  define VARIANT_INLINE //__declspec(noinline)
# endif
#else
# ifdef NDEBUG
#  define VARIANT_INLINE //inline __attribute__((always_inline))
# else
#  define VARIANT_INLINE __attribute__((noinline))
# endif
#endif
// clang-format on

// Exceptions
#if defined(__EXCEPTIONS) || defined(_MSC_VER)
#define HAS_EXCEPTIONS
#endif

#define VARIANT_MAJOR_VERSION 1
#define VARIANT_MINOR_VERSION 1
#define VARIANT_PATCH_VERSION 0

#define VARIANT_VERSION                                                        \
    (VARIANT_MAJOR_VERSION * 100000) + (VARIANT_MINOR_VERSION * 100) +         \
        (VARIANT_PATCH_VERSION)

namespace mapbox
{
namespace util
{

// XXX This should derive from std::logic_error instead of std::runtime_error.
//     See https://github.com/mapbox/variant/issues/48 for details.
class bad_variant_access : public std::runtime_error
{

  public:
    explicit bad_variant_access(const std::string& what_arg) :
        runtime_error(what_arg)
    {
    }

    explicit bad_variant_access(const char* what_arg) : runtime_error(what_arg)
    {
    }

}; // class bad_variant_access

template <typename R = void> struct MAPBOX_VARIANT_DEPRECATED static_visitor
{
    using result_type = R;

  protected:
    static_visitor()
    {
    }
    ~static_visitor()
    {
    }
};

namespace detail
{

static constexpr std::size_t invalid_value = std::size_t(-1);

template <typename T, typename... Types> struct direct_type;

template <typename T, typename First, typename... Types>
struct direct_type<T, First, Types...>
{
    static constexpr std::size_t index = std::is_same<T, First>::value
                                             ? sizeof...(Types)
                                             : direct_type<T, Types...>::index;
};

template <typename T> struct direct_type<T>
{
    static constexpr std::size_t index = invalid_value;
};

#if __cpp_lib_logical_traits >= 201510L

using std::disjunction;

#else

template <typename...> struct disjunction : std::false_type
{
};

template <typename B1> struct disjunction<B1> : B1
{
};

template <typename B1, typename B2>
struct disjunction<B1, B2> : std::conditional<B1::value, B1, B2>::type
{
};

template <typename B1, typename... Bs>
struct disjunction<B1, Bs...>
    : std::conditional<B1::value, B1, disjunction<Bs...>>::type
{
};

#endif

template <typename T, typename... Types> struct convertible_type;

template <typename T, typename First, typename... Types>
struct convertible_type<T, First, Types...>
{
    static constexpr std::size_t index =
        std::is_convertible<T, First>::value
            ? disjunction<std::is_convertible<T, Types>...>::value
                  ? invalid_value
                  : sizeof...(Types)
            : convertible_type<T, Types...>::index;
};

template <typename T> struct convertible_type<T>
{
    static constexpr std::size_t index = invalid_value;
};

template <typename T, typename... Types> struct value_traits
{
    using value_type = typename std::remove_const<
        typename std::remove_reference<T>::type>::type;
    static constexpr std::size_t direct_index =
        direct_type<value_type, Types...>::index;
    static constexpr bool is_direct = direct_index != invalid_value;
    static constexpr std::size_t index =
        is_direct ? direct_index
                  : convertible_type<value_type, Types...>::index;
    static constexpr bool is_valid = index != invalid_value;
    static constexpr std::size_t tindex =
        is_valid ? sizeof...(Types) - index : 0;
    using target_type =
        typename std::tuple_element<tindex, std::tuple<void, Types...>>::type;
};

template <typename T, typename R = void> struct enable_if_type
{
    using type = R;
};

template <typename F, typename V, typename Enable = void>
struct result_of_unary_visit
{
    using type = typename std::result_of<F(V&)>::type;
};

template <typename F, typename V>
struct result_of_unary_visit<
    F, V, typename enable_if_type<typename F::result_type>::type>
{
    using type = typename F::result_type;
};

template <typename F, typename V, typename Enable = void>
struct result_of_binary_visit
{
    using type = typename std::result_of<F(V&, V&)>::type;
};

template <typename F, typename V>
struct result_of_binary_visit<
    F, V, typename enable_if_type<typename F::result_type>::type>
{
    using type = typename F::result_type;
};

template <std::size_t arg1, std::size_t... others> struct static_max;

template <std::size_t arg> struct static_max<arg>
{
    static const std::size_t value = arg;
};

template <std::size_t arg1, std::size_t arg2, std::size_t... others>
struct static_max<arg1, arg2, others...>
{
    static const std::size_t value = arg1 >= arg2
                                         ? static_max<arg1, others...>::value
                                         : static_max<arg2, others...>::value;
};

template <typename... Types> struct variant_helper;

template <typename T, typename... Types> struct variant_helper<T, Types...>
{
    VARIANT_INLINE static void destroy(const std::size_t type_index, void* data)
    {
        if (type_index == sizeof...(Types))
        {
            reinterpret_cast<T*>(data)->~T();
        }
        else
        {
            variant_helper<Types...>::destroy(type_index, data);
        }
    }

    VARIANT_INLINE static void move(const std::size_t old_type_index,
                                    void* old_value, void* new_value)
    {
        if (old_type_index == sizeof...(Types))
        {
            new (new_value) T(std::move(*reinterpret_cast<T*>(old_value)));
        }
        else
        {
            variant_helper<Types...>::move(old_type_index, old_value,
                                           new_value);
        }
    }

    VARIANT_INLINE static void copy(const std::size_t old_type_index,
                                    const void* old_value, void* new_value)
    {
        if (old_type_index == sizeof...(Types))
        {
            new (new_value) T(*reinterpret_cast<const T*>(old_value));
        }
        else
        {
            variant_helper<Types...>::copy(old_type_index, old_value,
                                           new_value);
        }
    }
};

template <> struct variant_helper<>
{
    VARIANT_INLINE static void destroy(const std::size_t, void*)
    {
    }
    VARIANT_INLINE static void move(const std::size_t, void*, void*)
    {
    }
    VARIANT_INLINE static void copy(const std::size_t, const void*, void*)
    {
    }
};

template <typename T> struct unwrapper
{
    static T const& apply_const(T const& obj)
    {
        return obj;
    }
    static T& apply(T& obj)
    {
        return obj;
    }
};

template <typename T> struct unwrapper<recursive_wrapper<T>>
{
    static auto apply_const(recursive_wrapper<T> const& obj) ->
        typename recursive_wrapper<T>::type const&
    {
        return obj.get();
    }
    static auto apply(recursive_wrapper<T>& obj) ->
        typename recursive_wrapper<T>::type&
    {
        return obj.get();
    }
};

template <typename T> struct unwrapper<std::reference_wrapper<T>>
{
    static auto apply_const(std::reference_wrapper<T> const& obj) ->
        typename std::reference_wrapper<T>::type const&
    {
        return obj.get();
    }
    static auto apply(std::reference_wrapper<T>& obj) ->
        typename std::reference_wrapper<T>::type&
    {
        return obj.get();
    }
};

template <typename F, typename V, typename R, typename... Types>
struct dispatcher;

template <typename F, typename V, typename R, typename T, typename... Types>
struct dispatcher<F, V, R, T, Types...>
{
    VARIANT_INLINE static R apply_const(V const& v, F&& f)
    {
        if (v.template is<T>())
        {
            return f(unwrapper<T>::apply_const(v.template get_unchecked<T>()));
        }
        else
        {
            return dispatcher<F, V, R, Types...>::apply_const(
                v, std::forward<F>(f));
        }
    }

    VARIANT_INLINE static R apply(V& v, F&& f)
    {
        if (v.template is<T>())
        {
            return f(unwrapper<T>::apply(v.template get_unchecked<T>()));
        }
        else
        {
            return dispatcher<F, V, R, Types...>::apply(v, std::forward<F>(f));
        }
    }
};

template <typename F, typename V, typename R, typename T>
struct dispatcher<F, V, R, T>
{
    VARIANT_INLINE static R apply_const(V const& v, F&& f)
    {
        return f(unwrapper<T>::apply_const(v.template get_unchecked<T>()));
    }

    VARIANT_INLINE static R apply(V& v, F&& f)
    {
        return f(unwrapper<T>::apply(v.template get_unchecked<T>()));
    }
};

template <typename F, typename V, typename R, typename T, typename... Types>
struct binary_dispatcher_rhs;

template <typename F, typename V, typename R, typename T0, typename T1,
          typename... Types>
struct binary_dispatcher_rhs<F, V, R, T0, T1, Types...>
{
    VARIANT_INLINE static R apply_const(V const& lhs, V const& rhs, F&& f)
    {
        if (rhs.template is<T1>()) // call binary functor
        {
            return f(
                unwrapper<T0>::apply_const(lhs.template get_unchecked<T0>()),
                unwrapper<T1>::apply_const(rhs.template get_unchecked<T1>()));
        }
        else
        {
            return binary_dispatcher_rhs<F, V, R, T0, Types...>::apply_const(
                lhs, rhs, std::forward<F>(f));
        }
    }

    VARIANT_INLINE static R apply(V& lhs, V& rhs, F&& f)
    {
        if (rhs.template is<T1>()) // call binary functor
        {
            return f(unwrapper<T0>::apply(lhs.template get_unchecked<T0>()),
                     unwrapper<T1>::apply(rhs.template get_unchecked<T1>()));
        }
        else
        {
            return binary_dispatcher_rhs<F, V, R, T0, Types...>::apply(
                lhs, rhs, std::forward<F>(f));
        }
    }
};

template <typename F, typename V, typename R, typename T0, typename T1>
struct binary_dispatcher_rhs<F, V, R, T0, T1>
{
    VARIANT_INLINE static R apply_const(V const& lhs, V const& rhs, F&& f)
    {
        return f(unwrapper<T0>::apply_const(lhs.template get_unchecked<T0>()),
                 unwrapper<T1>::apply_const(rhs.template get_unchecked<T1>()));
    }

    VARIANT_INLINE static R apply(V& lhs, V& rhs, F&& f)
    {
        return f(unwrapper<T0>::apply(lhs.template get_unchecked<T0>()),
                 unwrapper<T1>::apply(rhs.template get_unchecked<T1>()));
    }
};

template <typename F, typename V, typename R, typename T, typename... Types>
struct binary_dispatcher_lhs;

template <typename F, typename V, typename R, typename T0, typename T1,
          typename... Types>
struct binary_dispatcher_lhs<F, V, R, T0, T1, Types...>
{
    VARIANT_INLINE static R apply_const(V const& lhs, V const& rhs, F&& f)
    {
        if (lhs.template is<T1>()) // call binary functor
        {
            return f(
                unwrapper<T1>::apply_const(lhs.template get_unchecked<T1>()),
                unwrapper<T0>::apply_const(rhs.template get_unchecked<T0>()));
        }
        else
        {
            return binary_dispatcher_lhs<F, V, R, T0, Types...>::apply_const(
                lhs, rhs, std::forward<F>(f));
        }
    }

    VARIANT_INLINE static R apply(V& lhs, V& rhs, F&& f)
    {
        if (lhs.template is<T1>()) // call binary functor
        {
            return f(unwrapper<T1>::apply(lhs.template get_unchecked<T1>()),
                     unwrapper<T0>::apply(rhs.template get_unchecked<T0>()));
        }
        else
        {
            return binary_dispatcher_lhs<F, V, R, T0, Types...>::apply(
                lhs, rhs, std::forward<F>(f));
        }
    }
};

template <typename F, typename V, typename R, typename T0, typename T1>
struct binary_dispatcher_lhs<F, V, R, T0, T1>
{
    VARIANT_INLINE static R apply_const(V const& lhs, V const& rhs, F&& f)
    {
        return f(unwrapper<T1>::apply_const(lhs.template get_unchecked<T1>()),
                 unwrapper<T0>::apply_const(rhs.template get_unchecked<T0>()));
    }

    VARIANT_INLINE static R apply(V& lhs, V& rhs, F&& f)
    {
        return f(unwrapper<T1>::apply(lhs.template get_unchecked<T1>()),
                 unwrapper<T0>::apply(rhs.template get_unchecked<T0>()));
    }
};

template <typename F, typename V, typename R, typename... Types>
struct binary_dispatcher;

template <typename F, typename V, typename R, typename T, typename... Types>
struct binary_dispatcher<F, V, R, T, Types...>
{
    VARIANT_INLINE static R apply_const(V const& v0, V const& v1, F&& f)
    {
        if (v0.template is<T>())
        {
            if (v1.template is<T>())
            {
                return f(
                    unwrapper<T>::apply_const(v0.template get_unchecked<T>()),
                    unwrapper<T>::apply_const(
                        v1.template get_unchecked<T>())); // call binary functor
            }
            else
            {
                return binary_dispatcher_rhs<F, V, R, T, Types...>::apply_const(
                    v0, v1, std::forward<F>(f));
            }
        }
        else if (v1.template is<T>())
        {
            return binary_dispatcher_lhs<F, V, R, T, Types...>::apply_const(
                v0, v1, std::forward<F>(f));
        }
        return binary_dispatcher<F, V, R, Types...>::apply_const(
            v0, v1, std::forward<F>(f));
    }

    VARIANT_INLINE static R apply(V& v0, V& v1, F&& f)
    {
        if (v0.template is<T>())
        {
            if (v1.template is<T>())
            {
                return f(
                    unwrapper<T>::apply(v0.template get_unchecked<T>()),
                    unwrapper<T>::apply(
                        v1.template get_unchecked<T>())); // call binary functor
            }
            else
            {
                return binary_dispatcher_rhs<F, V, R, T, Types...>::apply(
                    v0, v1, std::forward<F>(f));
            }
        }
        else if (v1.template is<T>())
        {
            return binary_dispatcher_lhs<F, V, R, T, Types...>::apply(
                v0, v1, std::forward<F>(f));
        }
        return binary_dispatcher<F, V, R, Types...>::apply(v0, v1,
                                                           std::forward<F>(f));
    }
};

template <typename F, typename V, typename R, typename T>
struct binary_dispatcher<F, V, R, T>
{
    VARIANT_INLINE static R apply_const(V const& v0, V const& v1, F&& f)
    {
        return f(unwrapper<T>::apply_const(v0.template get_unchecked<T>()),
                 unwrapper<T>::apply_const(
                     v1.template get_unchecked<T>())); // call binary functor
    }

    VARIANT_INLINE static R apply(V& v0, V& v1, F&& f)
    {
        return f(unwrapper<T>::apply(v0.template get_unchecked<T>()),
                 unwrapper<T>::apply(
                     v1.template get_unchecked<T>())); // call binary functor
    }
};

// comparator functors
struct equal_comp
{
    template <typename T> bool operator()(T const& lhs, T const& rhs) const
    {
        return lhs == rhs;
    }
};

struct less_comp
{
    template <typename T> bool operator()(T const& lhs, T const& rhs) const
    {
        return lhs < rhs;
    }
};

template <typename Variant, typename Comp> class comparer
{
  public:
    explicit comparer(Variant const& lhs) noexcept : lhs_(lhs)
    {
    }
    comparer& operator=(comparer const&) = delete;
    // visitor
    template <typename T> bool operator()(T const& rhs_content) const
    {
        T const& lhs_content = lhs_.template get_unchecked<T>();
        return Comp()(lhs_content, rhs_content);
    }

  private:
    Variant const& lhs_;
};

} // namespace detail

struct no_init
{
};

template <typename... Types> class variant
{
    static_assert(sizeof...(Types) > 0,
                  "Template parameter type list of variant can not be empty");
    static_assert(!detail::disjunction<std::is_reference<Types>...>::value,
                  "Variant can not hold reference types. Maybe use "
                  "std::reference_wrapper?");

  private:
    static const std::size_t data_size =
        detail::static_max<sizeof(Types)...>::value;
    static const std::size_t data_align =
        detail::static_max<alignof(Types)...>::value;

    using first_type =
        typename std::tuple_element<0, std::tuple<Types...>>::type;
    using data_type =
        typename std::aligned_storage<data_size, data_align>::type;
    using helper_type = detail::variant_helper<Types...>;

    std::size_t type_index;
    data_type data;

  public:
    VARIANT_INLINE variant() noexcept(
        std::is_nothrow_default_constructible<first_type>::value) :
        type_index(sizeof...(Types) - 1)
    {
        static_assert(std::is_default_constructible<first_type>::value,
                      "First type in variant must be default constructible to "
                      "allow default construction of variant");
        new (&data) first_type();
    }

    VARIANT_INLINE variant(no_init) noexcept : type_index(detail::invalid_value)
    {
    }

    // http://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers
    template <typename T, typename Traits = detail::value_traits<T, Types...>,
              typename Enable = typename std::enable_if<Traits::is_valid>::type>
    VARIANT_INLINE variant(T&& val) noexcept(
        std::is_nothrow_constructible<typename Traits::target_type,
                                      T&&>::value) :
        type_index(Traits::index)
    {
        new (&data) typename Traits::target_type(std::forward<T>(val));
    }

    VARIANT_INLINE variant(variant<Types...> const& old) :
        type_index(old.type_index)
    {
        helper_type::copy(old.type_index, &old.data, &data);
    }

    VARIANT_INLINE variant(variant<Types...>&& old) noexcept(
        std::is_nothrow_move_constructible<std::tuple<Types...>>::value) :
        type_index(old.type_index)
    {
        helper_type::move(old.type_index, &old.data, &data);
    }

  private:
    VARIANT_INLINE void copy_assign(variant<Types...> const& rhs)
    {
        helper_type::destroy(type_index, &data);
        type_index = detail::invalid_value;
        helper_type::copy(rhs.type_index, &rhs.data, &data);
        type_index = rhs.type_index;
    }

    VARIANT_INLINE void move_assign(variant<Types...>&& rhs)
    {
        helper_type::destroy(type_index, &data);
        type_index = detail::invalid_value;
        helper_type::move(rhs.type_index, &rhs.data, &data);
        type_index = rhs.type_index;
    }

  public:
    VARIANT_INLINE variant<Types...>& operator=(variant<Types...>&& other)
    {
        move_assign(std::move(other));
        return *this;
    }

    VARIANT_INLINE variant<Types...>& operator=(variant<Types...> const& other)
    {
        copy_assign(other);
        return *this;
    }

    // conversions
    // move-assign
    template <typename T>
    VARIANT_INLINE variant<Types...>& operator=(T&& rhs) noexcept
    {
        variant<Types...> temp(std::forward<T>(rhs));
        move_assign(std::move(temp));
        return *this;
    }

    // copy-assign
    template <typename T>
    VARIANT_INLINE variant<Types...>& operator=(T const& rhs)
    {
        variant<Types...> temp(rhs);
        copy_assign(temp);
        return *this;
    }

    template <typename T, typename std::enable_if<
                              (detail::direct_type<T, Types...>::index !=
                               detail::invalid_value)>::type* = nullptr>
    VARIANT_INLINE bool is() const
    {
        return type_index == detail::direct_type<T, Types...>::index;
    }

    template <typename T,
              typename std::enable_if<
                  (detail::direct_type<recursive_wrapper<T>, Types...>::index !=
                   detail::invalid_value)>::type* = nullptr>
    VARIANT_INLINE bool is() const
    {
        return type_index ==
               detail::direct_type<recursive_wrapper<T>, Types...>::index;
    }

    VARIANT_INLINE bool valid() const
    {
        return type_index != detail::invalid_value;
    }

    template <typename T, typename... Args>
    VARIANT_INLINE void set(Args&&... args)
    {
        helper_type::destroy(type_index, &data);
        type_index = detail::invalid_value;
        new (&data) T(std::forward<Args>(args)...);
        type_index = detail::direct_type<T, Types...>::index;
    }

    // get_unchecked<T>()
    template <typename T, typename std::enable_if<
                              (detail::direct_type<T, Types...>::index !=
                               detail::invalid_value)>::type* = nullptr>
    VARIANT_INLINE T& get_unchecked()
    {
        return *reinterpret_cast<T*>(&data);
    }

#ifdef HAS_EXCEPTIONS
    // get<T>()
    template <typename T, typename std::enable_if<
                              (detail::direct_type<T, Types...>::index !=
                               detail::invalid_value)>::type* = nullptr>
    VARIANT_INLINE T& get()
    {
        if (type_index == detail::direct_type<T, Types...>::index)
        {
            return *reinterpret_cast<T*>(&data);
        }
        else
        {
            throw bad_variant_access("in get<T>()");
        }
    }
#endif

    template <typename T, typename std::enable_if<
                              (detail::direct_type<T, Types...>::index !=
                               detail::invalid_value)>::type* = nullptr>
    VARIANT_INLINE T const& get_unchecked() const
    {
        return *reinterpret_cast<T const*>(&data);
    }

#ifdef HAS_EXCEPTIONS
    template <typename T, typename std::enable_if<
                              (detail::direct_type<T, Types...>::index !=
                               detail::invalid_value)>::type* = nullptr>
    VARIANT_INLINE T const& get() const
    {
        if (type_index == detail::direct_type<T, Types...>::index)
        {
            return *reinterpret_cast<T const*>(&data);
        }
        else
        {
            throw bad_variant_access("in get<T>()");
        }
    }
#endif

    // get_unchecked<T>() - T stored as recursive_wrapper<T>
    template <typename T,
              typename std::enable_if<
                  (detail::direct_type<recursive_wrapper<T>, Types...>::index !=
                   detail::invalid_value)>::type* = nullptr>
    VARIANT_INLINE T& get_unchecked()
    {
        return (*reinterpret_cast<recursive_wrapper<T>*>(&data)).get();
    }

#ifdef HAS_EXCEPTIONS
    // get<T>() - T stored as recursive_wrapper<T>
    template <typename T,
              typename std::enable_if<
                  (detail::direct_type<recursive_wrapper<T>, Types...>::index !=
                   detail::invalid_value)>::type* = nullptr>
    VARIANT_INLINE T& get()
    {
        if (type_index ==
            detail::direct_type<recursive_wrapper<T>, Types...>::index)
        {
            return (*reinterpret_cast<recursive_wrapper<T>*>(&data)).get();
        }
        else
        {
            throw bad_variant_access("in get<T>()");
        }
    }
#endif

    template <typename T,
              typename std::enable_if<
                  (detail::direct_type<recursive_wrapper<T>, Types...>::index !=
                   detail::invalid_value)>::type* = nullptr>
    VARIANT_INLINE T const& get_unchecked() const
    {
        return (*reinterpret_cast<recursive_wrapper<T> const*>(&data)).get();
    }

#ifdef HAS_EXCEPTIONS
    template <typename T,
              typename std::enable_if<
                  (detail::direct_type<recursive_wrapper<T>, Types...>::index !=
                   detail::invalid_value)>::type* = nullptr>
    VARIANT_INLINE T const& get() const
    {
        if (type_index ==
            detail::direct_type<recursive_wrapper<T>, Types...>::index)
        {
            return (*reinterpret_cast<recursive_wrapper<T> const*>(&data))
                .get();
        }
        else
        {
            throw bad_variant_access("in get<T>()");
        }
    }
#endif

    // get_unchecked<T>() - T stored as std::reference_wrapper<T>
    template <
        typename T,
        typename std::enable_if<
            (detail::direct_type<std::reference_wrapper<T>, Types...>::index !=
             detail::invalid_value)>::type* = nullptr>
    VARIANT_INLINE T& get_unchecked()
    {
        return (*reinterpret_cast<std::reference_wrapper<T>*>(&data)).get();
    }

#ifdef HAS_EXCEPTIONS
    // get<T>() - T stored as std::reference_wrapper<T>
    template <
        typename T,
        typename std::enable_if<
            (detail::direct_type<std::reference_wrapper<T>, Types...>::index !=
             detail::invalid_value)>::type* = nullptr>
    VARIANT_INLINE T& get()
    {
        if (type_index ==
            detail::direct_type<std::reference_wrapper<T>, Types...>::index)
        {
            return (*reinterpret_cast<std::reference_wrapper<T>*>(&data)).get();
        }
        else
        {
            throw bad_variant_access("in get<T>()");
        }
    }
#endif

    template <typename T,
              typename std::enable_if<
                  (detail::direct_type<std::reference_wrapper<T const>,
                                       Types...>::index !=
                   detail::invalid_value)>::type* = nullptr>
    VARIANT_INLINE T const& get_unchecked() const
    {
        return (*reinterpret_cast<std::reference_wrapper<T const> const*>(
                    &data))
            .get();
    }

#ifdef HAS_EXCEPTIONS
    template <typename T,
              typename std::enable_if<
                  (detail::direct_type<std::reference_wrapper<T const>,
                                       Types...>::index !=
                   detail::invalid_value)>::type* = nullptr>
    VARIANT_INLINE T const& get() const
    {
        if (type_index == detail::direct_type<std::reference_wrapper<T const>,
                                              Types...>::index)
        {
            return (*reinterpret_cast<std::reference_wrapper<T const> const*>(
                        &data))
                .get();
        }
        else
        {
            throw bad_variant_access("in get<T>()");
        }
    }
#endif

    // This function is deprecated because it returns an internal index field.
    // Use which() instead.
    MAPBOX_VARIANT_DEPRECATED VARIANT_INLINE std::size_t get_type_index() const
    {
        return type_index;
    }

    VARIANT_INLINE int which() const noexcept
    {
        return static_cast<int>(sizeof...(Types) - type_index - 1);
    }

    template <typename T, typename std::enable_if<
                              (detail::direct_type<T, Types...>::index !=
                               detail::invalid_value)>::type* = nullptr>
    VARIANT_INLINE static constexpr int which() noexcept
    {
        return static_cast<int>(sizeof...(Types) -
                                detail::direct_type<T, Types...>::index - 1);
    }

    // visitor
    // unary
    template <typename F, typename V,
              typename R =
                  typename detail::result_of_unary_visit<F, first_type>::type>
    auto VARIANT_INLINE static visit(V const& v, F&& f)
        -> decltype(detail::dispatcher<F, V, R, Types...>::apply_const(
            v, std::forward<F>(f)))
    {
        return detail::dispatcher<F, V, R, Types...>::apply_const(
            v, std::forward<F>(f));
    }
    // non-const
    template <typename F, typename V,
              typename R =
                  typename detail::result_of_unary_visit<F, first_type>::type>
    auto VARIANT_INLINE static visit(V& v, F&& f) -> decltype(
        detail::dispatcher<F, V, R, Types...>::apply(v, std::forward<F>(f)))
    {
        return detail::dispatcher<F, V, R, Types...>::apply(v,
                                                            std::forward<F>(f));
    }

    // binary
    // const
    template <typename F, typename V,
              typename R =
                  typename detail::result_of_binary_visit<F, first_type>::type>
    auto VARIANT_INLINE static binary_visit(V const& v0, V const& v1, F&& f)
        -> decltype(detail::binary_dispatcher<F, V, R, Types...>::apply_const(
            v0, v1, std::forward<F>(f)))
    {
        return detail::binary_dispatcher<F, V, R, Types...>::apply_const(
            v0, v1, std::forward<F>(f));
    }
    // non-const
    template <typename F, typename V,
              typename R =
                  typename detail::result_of_binary_visit<F, first_type>::type>
    auto VARIANT_INLINE static binary_visit(V& v0, V& v1, F&& f)
        -> decltype(detail::binary_dispatcher<F, V, R, Types...>::apply(
            v0, v1, std::forward<F>(f)))
    {
        return detail::binary_dispatcher<F, V, R, Types...>::apply(
            v0, v1, std::forward<F>(f));
    }

    ~variant() noexcept // no-throw destructor
    {
        helper_type::destroy(type_index, &data);
    }

    // comparison operators
    // equality
    VARIANT_INLINE bool operator==(variant const& rhs) const
    {
        assert(valid() && rhs.valid());
        if (this->which() != rhs.which())
        {
            return false;
        }
        detail::comparer<variant, detail::equal_comp> visitor(*this);
        return visit(rhs, visitor);
    }

    VARIANT_INLINE bool operator!=(variant const& rhs) const
    {
        return !(*this == rhs);
    }

    // less than
    VARIANT_INLINE bool operator<(variant const& rhs) const
    {
        assert(valid() && rhs.valid());
        if (this->which() != rhs.which())
        {
            return this->which() < rhs.which();
        }
        detail::comparer<variant, detail::less_comp> visitor(*this);
        return visit(rhs, visitor);
    }
    VARIANT_INLINE bool operator>(variant const& rhs) const
    {
        return rhs < *this;
    }
    VARIANT_INLINE bool operator<=(variant const& rhs) const
    {
        return !(*this > rhs);
    }
    VARIANT_INLINE bool operator>=(variant const& rhs) const
    {
        return !(*this < rhs);
    }
};

// unary visitor interface
// const
template <typename F, typename V>
auto VARIANT_INLINE apply_visitor(F&& f, V const& v)
    -> decltype(V::visit(v, std::forward<F>(f)))
{
    return V::visit(v, std::forward<F>(f));
}

// non-const
template <typename F, typename V>
auto VARIANT_INLINE apply_visitor(F&& f, V& v)
    -> decltype(V::visit(v, std::forward<F>(f)))
{
    return V::visit(v, std::forward<F>(f));
}

// binary visitor interface
// const
template <typename F, typename V>
auto VARIANT_INLINE apply_visitor(F&& f, V const& v0, V const& v1)
    -> decltype(V::binary_visit(v0, v1, std::forward<F>(f)))
{
    return V::binary_visit(v0, v1, std::forward<F>(f));
}

// non-const
template <typename F, typename V>
auto VARIANT_INLINE apply_visitor(F&& f, V& v0, V& v1)
    -> decltype(V::binary_visit(v0, v1, std::forward<F>(f)))
{
    return V::binary_visit(v0, v1, std::forward<F>(f));
}

    // getter interface

#ifdef HAS_EXCEPTIONS
template <typename ResultType, typename T>
auto get(T& var) -> decltype(var.template get<ResultType>())
{
    return var.template get<ResultType>();
}
#endif

template <typename ResultType, typename T> ResultType& get_unchecked(T& var)
{
    return var.template get_unchecked<ResultType>();
}

#ifdef HAS_EXCEPTIONS
template <typename ResultType, typename T>
auto get(T const& var) -> decltype(var.template get<ResultType>())
{
    return var.template get<ResultType>();
}
#endif

template <typename ResultType, typename T>
ResultType const& get_unchecked(T const& var)
{
    return var.template get_unchecked<ResultType>();
}
} // namespace util
} // namespace mapbox

#endif // MAPBOX_UTIL_VARIANT_HPP
