// xstddef internal header -*-c++-*-
// Copyright 2009-2017 IAR Systems AB.
#ifndef _XSTDDEF_
#define _XSTDDEF_

#ifndef _SYSTEM_BUILD
  #pragma system_include
#endif

#include <xstddef0>
#include <cstddef>
#include <cstdlib>
#include <initializer_list>

#include <xtr1common>

namespace std {

// typename KEYWORD
#ifndef _TEMPLATE_STAT
/*  #define _TEMPLATE_STAT        template<> */
#endif

// MISCELLANEOUS MACROS
#define _EMPTY_ARGUMENT         /* for empty macro argument */

// TYPE DEFINITIONS
template<bool,
         class _Ty1,
         class _Ty2>
struct _If
{       // type is _Ty2 for assumed false
  typedef _Ty2 type;
};

template<class _Ty1,
         class _Ty2>
struct _If<true, _Ty1, _Ty2>
{       // type is _Ty1 for assumed true
  typedef _Ty1 type;
};

template<class _Ty>
struct _Always_false
{       // false value that probably won't be optimized away
  static const bool value = false;
};

#ifndef _STATIC_ASSERT2
  #define _STATIC_ASSERT2(test, mesg)             \
    ((void)_Static_assert<test>(mesg))

  template<bool>
  struct _Static_assert;  // leave false undefined

  template<>
  struct _Static_assert<true>
  {       // assertion is met
    _Static_assert(const char *)
    {       // construct from message
    };
  };
#endif /* _STATIC_ASSERT2 */

//      FUNCTIONAL STUFF (from <functional>)
// TEMPLATE STRUCT unary_function
template<class _Arg,
         class _Result>
struct unary_function
{       // base class for unary functions
  typedef _Arg argument_type;
  typedef _Result result_type;
};

// TEMPLATE STRUCT binary_function
template<class _Arg1,
         class _Arg2,
         class _Result>
struct binary_function
{       // base class for binary functions
  typedef _Arg1 first_argument_type;
  typedef _Arg2 second_argument_type;
  typedef _Result result_type;
};

// TEMPLATE STRUCT plus
template<class _Ty = void>
struct plus
{	// functor for operator+
  typedef _Ty first_argument_type;
  typedef _Ty second_argument_type;
  typedef _Ty result_type;

  constexpr _Ty operator()(const _Ty& _Left, const _Ty& _Right) const
  {	// apply operator+ to operands
    return _Left + _Right;
  }
};

  // TEMPLATE STRUCT minus
template<class _Ty = void>
struct minus
{	// functor for operator-
  typedef _Ty first_argument_type;
  typedef _Ty second_argument_type;
  typedef _Ty result_type;

  constexpr _Ty operator()(const _Ty& _Left, const _Ty& _Right) const
  {	// apply operator- to operands
    return _Left - _Right;
  }
};

  // TEMPLATE STRUCT multiplies
template<class _Ty = void>
struct multiplies
{	// functor for operator*
  typedef _Ty first_argument_type;
  typedef _Ty second_argument_type;
  typedef _Ty result_type;

  constexpr _Ty operator()(const _Ty& _Left, const _Ty& _Right) const
  {	// apply operator* to operands
    return _Left * _Right;
  }
};

  // TEMPLATE STRUCT equal_to
template<class _Ty = void>
struct equal_to
{	// functor for operator==
  typedef _Ty first_argument_type;
  typedef _Ty second_argument_type;
  typedef bool result_type;

  constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const
  {	// apply operator== to operands
    return _Left == _Right;
  }
};

  // TEMPLATE STRUCT less
template<class _Ty = void>
struct less
{	// functor for operator<
  typedef _Ty first_argument_type;
  typedef _Ty second_argument_type;
  typedef bool result_type;

  constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const
  {	// apply operator< to operands
    return _Left < _Right;
  }
};

// is_transparent MACHINERY
typedef int _Is_trans;  // type for is_transparent

// TEMPLATE STRUCT SPECIALIZATION plus
template<>
struct plus<void>
{       // transparent functor for operator+
  typedef _Is_trans is_transparent;

  template<class _Ty1,
           class _Ty2>
  constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
    -> decltype(static_cast<_Ty1 &&>(_Left) + static_cast<_Ty2 &&>(_Right))
  {       // transparently apply operator+ to operands
    return static_cast<_Ty1 &&>(_Left) + static_cast<_Ty2 &&>(_Right);
  }
};

// TEMPLATE STRUCT SPECIALIZATION minus
template<>
struct minus<void>
{       // transparent functor for operator-
  typedef _Is_trans is_transparent;

  template<class _Ty1,
           class _Ty2>
  constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
      -> decltype(static_cast<_Ty1 &&>(_Left) - static_cast<_Ty2 &&>(_Right))
  {       // transparently apply operator- to operands
    return static_cast<_Ty1 &&>(_Left) - static_cast<_Ty2 &&>(_Right);
  }
};

// TEMPLATE STRUCT SPECIALIZATION multiplies
template<>
struct multiplies<void>
{       // transparent functor for operator*
  typedef _Is_trans is_transparent;

  template<class _Ty1,
           class _Ty2>
  constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
    -> decltype(static_cast<_Ty1 &&>(_Left) * static_cast<_Ty2 &&>(_Right))
  {       // transparently apply operator* to operands
    return static_cast<_Ty1 &&>(_Left) * static_cast<_Ty2 &&>(_Right);
  }
};

// TEMPLATE STRUCT SPECIALIZATION equal_to
template<>
struct equal_to<void>
{       // transparent functor for operator==
  typedef _Is_trans is_transparent;

  template<class _Ty1,
           class _Ty2>
  constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
    -> decltype(static_cast<_Ty1 &&>(_Left) == static_cast<_Ty2 &&>(_Right))
  {       // transparently apply operator== to operands
    return static_cast<_Ty1 &&>(_Left) == static_cast<_Ty2 &&>(_Right);
  }
};

// TEMPLATE STRUCT SPECIALIZATION less
template<>
struct less<void>
{       // transparent functor for operator<
  typedef _Is_trans is_transparent;

  template<class _Ty1,
           class _Ty2>
  constexpr auto operator()(_Ty1&& _Left, _Ty2&& _Right) const
    -> decltype(static_cast<_Ty1 &&>(_Left) < static_cast<_Ty2 &&>(_Right))
  {       // transparently apply operator< to operands
    return static_cast<_Ty1 &&>(_Left) < static_cast<_Ty2 &&>(_Right);
    }
};

#define _FUNCTOR(func, iter)    func<>()

#ifndef _HASH_SEQ_DEFINED
  #define _HASH_SEQ_DEFINED

  // FUNCTION _Hash_seq
  #pragma no_arith_checks
  inline size_t _Hash_seq(const unsigned char *_First, size_t _Count)
  { // Simple hash function for bytes in [_First, _First + _Count)
  #if __LONG_LONG_SIZE__ == 8
    #if __SIZE_T_MAX__ == 0xFFFFFFFFFFFFFFFF // 64 bit
      #define __USE_64BIT_HASH_SEQ__
    #endif
  #endif
  #ifdef __USE_64BIT_HASH_SEQ__
    #undef __USE_64BIT_HASH_SEQ__
    const size_t _FNV_offset_basis = 14695981039346656037ULL;
    const size_t _FNV_prime = 1099511628211ULL;
    size_t _Val = _FNV_offset_basis;
    for (size_t _Next = 0; _Next < _Count; ++_Next)
    {	// fold in another byte
      _Val ^= (size_t)_First[_Next];
      _Val *= _FNV_prime;
    }
  #else // 32-bit or smaller
    _STATIC_ASSERT2(__SIZE_T_MAX__ <= 0xFFFFFFFFUL, "Needs better algorithm");

    size_t _Val = 0;
    for (size_t _Next = 0; _Next < _Count; ++_Next)
    { // fold in another byte
      _Val += (size_t)_First[_Next];
      // _Val *= 31;
      _Val = (_Val << 5) - _Val;
    }
  #endif
    return _Val;
  }

  // TEMPLATE STRUCT _Bitwise_hash
  template<class _Kty>
  struct _Bitwise_hash
  {       // hash functor for plain old data
    typedef _Kty argument_type;
    typedef size_t result_type;

    size_t operator()(const _Kty& _Keyval) const
    {	// hash _Keyval to size_t value by pseudorandomizing transform
      return _Hash_seq((const unsigned char *)&_Keyval, sizeof (_Kty));
    }
  };

  // TEMPLATE STRUCT hash
  template<class _Kty>
  struct hash
    : public _Bitwise_hash<_Kty>
  {       // hash functor for enums
  };
  template<>
  struct hash<bool>
    : public _Bitwise_hash<bool>
  {       // hash functor for bool
  };

  template<>
  struct hash<char>
    : public _Bitwise_hash<char>
  {       // hash functor for char
  };

  template<>
  struct hash<signed char>
    : public _Bitwise_hash<signed char>
  {       // hash functor for signed char
  };

  template<>
  struct hash<unsigned char>
    : public _Bitwise_hash<unsigned char>
  {       // hash functor for unsigned char
  };

  template<>
  struct hash<char16_t>
    : public _Bitwise_hash<char16_t>
  {       // hash functor for char16_t
  };

  template<>
  struct hash<char32_t>
    : public _Bitwise_hash<char32_t>
  {       // hash functor for char32_t
  };

  template<>
  struct hash<wchar_t>
    : public _Bitwise_hash<wchar_t>
  {       // hash functor for wchar_t
  };

  template<>
  struct hash<short>
    : public _Bitwise_hash<short>
  {       // hash functor for short
  };

  template<>
  struct hash<unsigned short>
    : public _Bitwise_hash<unsigned short>
  {       // hash functor for unsigned short
  };

  template<>
  struct hash<int>
    : public _Bitwise_hash<int>
  {       // hash functor for int
  };

  template<>
  struct hash<unsigned int>
    : public _Bitwise_hash<unsigned int>
  {       // hash functor for unsigned int
  };

  template<>
  struct hash<long>
    : public _Bitwise_hash<long>
  {       // hash functor for long
  };

  template<>
  struct hash<unsigned long>
    : public _Bitwise_hash<unsigned long>
  {       // hash functor for unsigned long
  };

  template<>
  struct hash<long long>
    : public _Bitwise_hash<long long>
  {       // hash functor for long long
  };

  template<>
  struct hash<unsigned long long>
    : public _Bitwise_hash<unsigned long long>
  {       // hash functor for unsigned long long
  };

  template<>
  struct hash<float>
    : public _Bitwise_hash<float>
  {       // hash functor for float
    typedef float _Kty;
    typedef _Bitwise_hash<_Kty> _Mybase;

    size_t operator()(const _Kty& _Keyval) const
    {       // hash _Keyval to size_t value by pseudorandomizing transform
      return _Mybase::operator()(_Keyval == 0 ? 0 : _Keyval); // map -0 to 0
    }
  };

  template<>
  struct hash<double>
    : public _Bitwise_hash<double>
  {       // hash functor for double
    typedef double _Kty;
    typedef _Bitwise_hash<_Kty> _Mybase;

    size_t operator()(const _Kty& _Keyval) const
    {       // hash _Keyval to size_t value by pseudorandomizing transform
      return _Mybase::operator()(_Keyval == 0 ? 0 : _Keyval); // map -0 to 0
    }
  };

  template<>
  struct hash<long double>
    : public _Bitwise_hash<long double>
  {       // hash functor for long double
    typedef long double _Kty;
    typedef _Bitwise_hash<_Kty> _Mybase;

    size_t operator()(const _Kty& _Keyval) const
    {       // hash _Keyval to size_t value by pseudorandomizing transform
      return _Mybase::operator()(_Keyval == 0 ? 0 : _Keyval); // map -0 to 0
    }
  };

  template<class _Ty>
  struct hash<_Ty *>
    : public _Bitwise_hash<_Ty *>
  {       // hash functor for _Ty *
  };
#endif /* _HASH_SEQ_DEFINED */

}       // namespace std

#define _MEMBER_CALL_CV(FUNC, REF_OPT)   \
  FUNC(, , REF_OPT)                      \
  FUNC(, const, REF_OPT)                 \
  FUNC(, volatile, REF_OPT)              \
  FUNC(, const volatile, REF_OPT)

#define _NON_MEMBER_CALL(FUNC)           \
  FUNC(_EMPTY_ARGUMENT)

#define _MEMBER_CALL_CV_REF(FUNC)        \
  _MEMBER_CALL_CV(FUNC, )                \
  _MEMBER_CALL_CV(FUNC, &)               \
  _MEMBER_CALL_CV(FUNC, &&)

#define _CLASS_DEFINE_CONST(CLASS)       \
  CLASS(_EMPTY_ARGUMENT)                 \
  CLASS(const)

#define _CLASS_DEFINE_CV(CLASS)          \
  CLASS(_EMPTY_ARGUMENT)                 \
  CLASS(const)                           \
  CLASS(volatile)                        \
  CLASS(const volatile)

#define _CLASS_DEFINE_CV_REF(CLASS)      \
  CLASS( , )                             \
  CLASS(const, )                         \
  CLASS(volatile, )                      \
  CLASS(const volatile, )                \
  CLASS( , &)                            \
  CLASS(const, &)                        \
  CLASS(volatile, &)                     \
  CLASS(const volatile, &)               \
  CLASS( , &&)                           \
  CLASS(const, &&)                       \
  CLASS(volatile, &&)                    \
  CLASS(const volatile, &&)

#define _COMMA  ,       /* for immediate commas in macro parameters */

namespace std {

  // TEMPLATE CLASS _Arg_types
template<class... _Types>
struct _Arg_types
{	// provide argument_type, etc. (sometimes)
};

template<class _Ty1>
struct _Arg_types<_Ty1>
{	// provide argument_type, etc. (sometimes)
  typedef _Ty1 argument_type;
};

template<class _Ty1,
         class _Ty2>
struct _Arg_types<_Ty1, _Ty2>
{	// provide argument_type, etc. (sometimes)
  typedef _Ty1 first_argument_type;
  typedef _Ty2 second_argument_type;
};

// TEMPLATE CLASS is_function
template<class _Ty>
struct _Is_function
{	// determine whether _Ty is a function
  typedef false_type _Bool_type;
};

#define _IS_FUNCTION(CALL_OPT, CV_OPT, REF_OPT)           \
  template<class _Ret,                                    \
           class... _Types>                               \
  struct _Is_function<_Ret CALL_OPT (_Types...) CV_OPT REF_OPT> \
    : _Arg_types<_Types...>                               \
  {	/* determine whether _Ty is a function */         \
    typedef true_type _Bool_type;                         \
    typedef _Ret result_type;                             \
  };

_MEMBER_CALL_CV_REF(_IS_FUNCTION)
#undef _IS_FUNCTION

#define _IS_FUNCTION_ELLIPSIS(CALL_OPT, CV_OPT, REF_OPT)  \
template<class _Ret,                                      \
         class... _Types>                                 \
struct _Is_function<_Ret (_Types..., ...) CV_OPT REF_OPT> \
{	/* no calling conventions for ellipsis */         \
  typedef true_type _Bool_type;                           \
  typedef _Ret result_type;                               \
};

_MEMBER_CALL_CV_REF(_IS_FUNCTION_ELLIPSIS)
#undef _IS_FUNCTION_ELLIPSIS

template<class _Ty>
struct is_function
  : _Is_function<_Ty>::_Bool_type
{	// determine whether _Ty is a function
};

// TEMPLATE FUNCTION addressof
template<class _Ty> inline
_Ty *_Addressof(_Ty& _Val, true_type) _NOEXCEPT
{	// return address of function _Val
  return _Val;
}

template<class _Ty> inline
_Ty *_Addressof(_Ty& _Val, false_type) _NOEXCEPT
{	// return address of object _Val
  return reinterpret_cast<_Ty *>(&const_cast<char&>(
                               reinterpret_cast<const volatile char&>(_Val)));
}

template<class _Ty> inline
_Ty *addressof(_Ty& _Val) _NOEXCEPT
{	// return address of _Val
  return _Addressof(_Val, is_function<_Ty>());
}

} // namespace std

#endif /* _XSTDDEF_ */

/*
 * Copyright (c) by P.J. Plauger. All rights reserved.
 * Consult your license regarding permissions and restrictions.
V6.50:0576 */
