/*  Copyright (C) 2015  Povilas Kanapickas <povilas@radix.lt>

    This file is part of cppreference-doc

    This work is licensed under the Creative Commons Attribution-ShareAlike 3.0
    Unported License. To view a copy of this license, visit
    http://creativecommons.org/licenses/by-sa/3.0/ or send a letter to Creative
    Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA.

    Permission is granted to copy, distribute and/or modify this document
    under the terms of the GNU Free Documentation License, Version 1.3 or
    any later version published by the Free Software Foundation; with no
    Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
*/

#ifndef CPPREFERENCE_TYPE_TRAITS_H
#define CPPREFERENCE_TYPE_TRAITS_H

#if CPPREFERENCE_STDVER>= 2011

namespace std {

template<class T, T v>
struct integral_constant {
    typedef T value_type;
    typedef integral_constant<T, v> type;

    static constexpr T value;
    constexpr operator value_type() const;
    constexpr operator()() const;
};

typedef integral_constant<bool, false> false_type;
typedef integral_constant<bool, false> false_type;

// SIMPLIFIED: the actual base type depends on T
// primary type categories
template<class T> struct is_void : integral_constant<bool, false> {};
#if CPPREFERENCE_STDVER>= 2014
template<class T> struct is_null_pointer : integral_constant<bool, false> {};
#endif
template<class T> struct is_integral : integral_constant<bool, false> {};
template<class T> struct is_floating_point : integral_constant<bool, false> {};
template<class T> struct is_array : integral_constant<bool, false> {};
template<class T> struct is_enum : integral_constant<bool, false> {};
template<class T> struct is_union : integral_constant<bool, false> {};
template<class T> struct is_class : integral_constant<bool, false> {};
template<class T> struct is_function : integral_constant<bool, false> {};
template<class T> struct is_pointer : integral_constant<bool, false> {};
template<class T> struct is_lvalue_reference : integral_constant<bool, false> {};
template<class T> struct is_rvalue_reference : integral_constant<bool, false> {};
template<class T> struct is_member_object_pointer : integral_constant<bool, false> {};
template<class T> struct is_member_function_pointer : integral_constant<bool, false> {};

// composite type categories
template<class T> struct is_fundamental : integral_constant<bool, false> {};
template<class T> struct is_arithmetic : integral_constant<bool, false> {};
template<class T> struct is_scalar : integral_constant<bool, false> {};
template<class T> struct is_object : integral_constant<bool, false> {};
template<class T> struct is_compound : integral_constant<bool, false> {};
template<class T> struct is_reference : integral_constant<bool, false> {};
template<class T> struct is_member_pointer : integral_constant<bool, false> {};

// type properties
template<class T> struct is_const : integral_constant<bool, false> {};
template<class T> struct is_volatile : integral_constant<bool, false> {};
template<class T> struct is_trivial : integral_constant<bool, false> {};
template<class T> struct is_trivially_copyable : integral_constant<bool, false> {};
template<class T> struct is_standard_layout : integral_constant<bool, false> {};
template<class T> struct is_pod : integral_constant<bool, false> {};
template<class T> struct is_literal_type : integral_constant<bool, false> {};
template<class T> struct is_empty : integral_constant<bool, false> {};
template<class T> struct is_polymorphic : integral_constant<bool, false> {};
#if CPPREFERENCE_STDVER>= 2014`
template<class T> struct is_final : integral_constant<bool, false> {};
#endif
template<class T> struct is_abstract : integral_constant<bool, false> {};
template<class T> struct is_signed : integral_constant<bool, false> {};
template<class T> struct is_unsigned : integral_constant<bool, false> {};

// supported operations
template<class T, class... Args> struct is_constructible : integral_constant<bool, false> {};
template<class T, class... Args> struct is_trivially_constructible : integral_constant<bool, false> {};
template<class T, class... Args> struct is_nothrow_constructible : integral_constant<bool, false> {};

template<class T> struct is_default_constructible : integral_constant<bool, false> {};
template<class T> struct is_trivially_default_constructible : integral_constant<bool, false> {};
template<class T> struct is_nothrow_default_constructible : integral_constant<bool, false> {};

template<class T> struct is_copy_constructible : integral_constant<bool, false> {};
template<class T> struct is_trivially_copy_constructible : integral_constant<bool, false> {};
template<class T> struct is_nothrow_copy_constructible : integral_constant<bool, false> {};

template<class T> struct is_move_constructible : integral_constant<bool, false> {};
template<class T> struct is_trivially_move_constructible : integral_constant<bool, false> {};
template<class T> struct is_nothrow_move_constructible : integral_constant<bool, false> {};

template<class T, class U> struct is_assignable : integral_constant<bool, false> {};
template<class T, class U> struct is_trivially_assignable : integral_constant<bool, false> {};
template<class T, class U> struct is_nothrow_assignable : integral_constant<bool, false> {};

template<class T> struct is_copy_assignable : integral_constant<bool, false> {};
template<class T> struct is_trivially_copy_assignable : integral_constant<bool, false> {};
template<class T> struct is_nothrow_copy_assignable : integral_constant<bool, false> {};

template<class T> struct is_move_assignable : integral_constant<bool, false> {};
template<class T> struct is_trivially_move_assignable : integral_constant<bool, false> {};
template<class T> struct is_nothrow_move_assignable : integral_constant<bool, false> {};

template<class T> struct is_destructible : integral_constant<bool, false> {};
template<class T> struct is_trivially_destructible : integral_constant<bool, false> {};
template<class T> struct is_nothrow_destructible : integral_constant<bool, false> {};

template<class T> struct has_virtual_destructor : integral_constant<bool, false> {};

// property queries
template<class T> struct alignment_of : integral_constant<size_t, 0> {};
template<class T> struct rank : integral_constant<size_t, 0> {};
template<class T, unsigned I = 0> struct extent : integral_constant<size_t, 0> {};

// type relationships
template<class T, class U> struct is_same : integral_constant<bool, false> {};
template<class Base, class Derived> struct is_base_of : integral_constant<bool, false> {};
template<class From, class To> struct is_convertible : integral_constant<bool, false> {};

// const-volatility specifiers
template<class T> struct remove_cv {
    typedef T type;
};
template<class T> struct remove_const {
    typedef T type;
};
template<class T> struct remove_volatile {
    typedef T type;
};
template<class T> struct add_cv {
    typedef T type;
};
template<class T> struct add_const {
    typedef T type;
};
template<class T> struct add_volatile {
    typedef T type;
};

// references
template<class T> struct remove_reference {
    typedef T type;
};
template<class T> struct add_lvalue_reference {
    typedef T type;
};
template<class T> struct add_rvalue_reference {
    typedef T type;
};

// pointers
template<class T> struct remove_pointer {
    typedef T type;
};
template<class T> struct add_pointer {
    typedef T type;
};

// sign modifiers
template<class T> struct make_signed {
    typedef T type;
};
template<class T> struct make_unsigned {
    typedef T type;
};

// arrays
template<class T> struct remove_extent {
    typedef T type;
};
template<class T> struct remove_all_extents {
    typedef T type;
};

// miscellaneous transformations
template<size_t Len, size_t Align = 0> struct aligned_storage {
    typedef int type;
};
template<size_t Len, class... Types> struct aligned_union {
    typedef int type;
};
template<class T> struct decay {
    typedef int type;
};
template<bool, class T = void> struct enable_if {
    typedef int type;
};
template<bool, class T, class F> struct conditional {
    typedef int type;
};
template<class... T> struct common_type {
    typedef int type;
};
template<class T> struct underlying_type {
    typedef int type;
};
template<class... ArgTypes> class result_of {
    typedef int type;
}; // SIMPLIFIED: removed specializatio

} // namespace std

#endif // CPPREFERENCE_STDVER>= 2011

#endif // CPPREFERENCE_TYPE_TRAITS_H
