// xstddef0 internal header -*-c++-*-
// Common macros with dlib5/xstddef.
// Copyright 2020 IAR Systems AB.
#ifndef _XSTDDEF0_
#define _XSTDDEF0_

#ifndef _SYSTEM_BUILD
  #pragma system_include
#endif

#include <ycheck.h>
#include <yvals.h>

// EXCEPTION MACROS
#ifndef _THROWS
  #if _HAS_NOEXCEPT || !_HAS_EXCEPTIONS
    #define _THROWS(x)
  #else
    #define _THROWS(x)    throw (x)
  #endif
#endif

#if _HAS_EXCEPTIONS
  #define _TRY_BEGIN     try {
  #define _CATCH(x)      } catch (x) {
  #define _CATCH_ALL     } catch (...) {
  #define _CATCH_END     }

  #if ! _EXCEPTION_NEUTRAL
    #define _RAISE(x)      throw (x)
  #else
    #define _RAISE(x)  static_assert(_Always_false<decltype(x)>::value, "_RAISE used when exception neutral")
  #endif

  #define _RERAISE       throw

  #if _HAS_NOEXCEPT
    #define _THROW0()             noexcept
  #else
    #define _THROW0()             throw ()
  #endif
#else /* _HAS_EXCEPTIONS */
  #define _TRY_BEGIN     { if (1) {
  #define _CATCH(x)      } else if (0) {
  #define _CATCH_ALL     } else if (0) {
  #define _CATCH_END     } }

  #define _RAISE(x)
  #define _RERAISE

  #define _THROW0()
  #define _THROW1(x)
#endif /* _HAS_EXCEPTIONS */

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

// BITMASK MACROS
#define _BITMASK(Enum, Ty)     typedef Enum Ty

#define _BITMASK_OPS(Ty)                                        \
  _Pragma("no_arith_checks")                                    \
  inline Ty& operator&=(Ty& _Left, Ty _Right)                   \
  {       /* return _Left &= _Right */                          \
    _Left = (Ty)((int)_Left & (int)_Right); return _Left;       \
  }                                                             \
                                                                \
  _Pragma("no_arith_checks")                                    \
  inline Ty& operator|=(Ty& _Left, Ty _Right)                   \
  {       /* return _Left |= _Right */                          \
    _Left = (Ty)((int)_Left | (int)_Right); return _Left;       \
  }                                                             \
                                                                \
  _Pragma("no_arith_checks")                                    \
  inline Ty& operator^=(Ty& _Left, Ty _Right)                   \
  {       /* return _Left ^= _Right */                          \
    _Left = (Ty)((int)_Left ^ (int)_Right); return _Left;       \
  }                                                             \
                                                                \
  _Pragma("no_arith_checks")                                    \
  inline constexpr Ty operator&(Ty _Left, Ty _Right)            \
  {       /* return _Left & _Right */                           \
    return (Ty)((int)_Left & (int)_Right);                      \
  }                                                             \
                                                                \
  _Pragma("no_arith_checks")                                    \
  inline constexpr Ty operator|(Ty _Left, Ty _Right)            \
  {       /* return _Left | _Right */                           \
    return (Ty)((int)_Left | (int)_Right);                      \
  }                                                             \
                                                                \
  _Pragma("no_arith_checks")                                    \
  inline constexpr Ty operator^(Ty _Left, Ty _Right)            \
  {       /* return _Left ^ _Right */                           \
    return (Ty)((int)_Left ^ (int)_Right);                      \
  }                                                             \
                                                                \
  _Pragma("no_arith_checks")                                    \
  inline constexpr Ty operator~(Ty _Left)                       \
  {       /* return ~_Left */                                   \
    return (Ty)~(int)_Left;                                     \
  }



#endif // _XSTDDEF0_
