/*
Copyright 2022-2023 Gabriel Jensen.
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at <https://mozilla.org/MPL/2.0>.
*/
#ifndef zap_priv_cxxhdr_bs
#define zap_priv_cxxhdr_bs
// C++11: constexpr
// C++14: template variables
#ifndef __cplusplus
#error C++ header included from C!
#endif
#include <zap/sys.hh>
#include <zap/bs.h>
namespace zap {
namespace impl {
template<typename typ> struct minval {constexpr static typ val = {};};
template<> struct minval<bool> {constexpr static auto val = false;};
template<> struct minval<signed char> {constexpr static auto val = zap_minvalsc;};
template<> struct minval<short> {constexpr static auto val = zap_minvals;};
template<> struct minval<int> {constexpr static auto val = zap_minvali;};
template<> struct minval<long> {constexpr static auto val = zap_minvall;};
template<> struct minval<long long> {constexpr static auto val = zap_minvalll;};
template<> struct minval<unsigned char> {constexpr static auto val = zap_minvaluc;};
template<> struct minval<unsigned short> {constexpr static auto val = zap_minvalus;};
template<> struct minval<unsigned int> {constexpr static auto val = zap_minvalui;};
template<> struct minval<unsigned long> {constexpr static auto val = zap_minvalul;};
template<> struct minval<unsigned long long> {constexpr static auto val = zap_minvalull;};
template<> struct minval<char> {constexpr static auto val = zap_minvalc;};
template<> struct minval<wchar_t> {constexpr static auto val = zap_minvalwc;};
#if __cpp_char8_t >= 201811
template<> struct minval<char8_t> {constexpr static auto val = zap_minvaluc;};
#endif
template<> struct minval<char16_t> {constexpr static auto val = zap_minval01;};
template<> struct minval<char32_t> {constexpr static auto val = zap_minval02;};
template<typename typ> struct maxval {constexpr static typ val = {};};
template<> struct maxval<bool> {constexpr static auto val = true;};
template<> struct maxval<signed char> {constexpr static auto val = zap_maxvalsc;};
template<> struct maxval<int> {constexpr static auto val = zap_maxvali;};
template<> struct maxval<short> {constexpr static auto val = zap_maxvals;};
template<> struct maxval<long> {constexpr static auto val = zap_maxvall;};
template<> struct maxval<long long> {constexpr static auto val = zap_maxvalll;};
template<> struct maxval<unsigned char> {constexpr static auto val = zap_maxvaluc;};
template<> struct maxval<unsigned short> {constexpr static auto val = zap_maxvalus;};
template<> struct maxval<unsigned int> {constexpr static auto val = zap_maxvalui;};
template<> struct maxval<unsigned long> {constexpr static auto val = zap_maxvalul;};
template<> struct maxval<unsigned long long> {constexpr static auto val = zap_maxvalull;};
template<> struct maxval<char> {constexpr static auto val = zap_maxvalc;};
template<> struct maxval<wchar_t> {constexpr static auto val = zap_maxvalwc;};
#if __cpp_char8_t >= 201811
template<> struct maxval<char8_t> {constexpr static auto val = zap_maxvaluc;};
#endif
template<> struct maxval<char16_t> {constexpr static auto val = zap_maxval01;};
template<> struct maxval<char32_t> {constexpr static auto val = zap_maxval02;};
}
template<typename typ> constexpr auto minval = ::zap::impl::minval<typ>::val;
template<typename typ> constexpr auto maxval = ::zap::impl::maxval<typ>::val;
}
namespace zap {
namespace impl {
template<typename ityp> struct sign {using typ = ityp;};
template<> struct sign<unsigned char> {using typ = signed char;};
template<> struct sign<unsigned int> {using typ = int;};
template<> struct sign<unsigned long> {using typ = long;};
template<> struct sign<unsigned long long> {using typ = long long;};
template<> struct sign<unsigned short> {using typ = short;};
template<typename ityp> struct usign {using typ = ityp;};
template<> struct usign<signed char> {using typ = unsigned char;};
template<> struct usign<int> {using typ = unsigned int;};
template<> struct usign<long> {using typ = unsigned long;};
template<> struct usign<long long> {using typ = unsigned long long;};
template<> struct usign<short> {using typ = unsigned short;};
}
template<typename typ> using sign = typename ::zap::impl::sign<typ>::typ;
template<typename typ> using usign = typename ::zap::impl::usign<typ>::typ;
}
namespace zap {
namespace impl {
template<typename ityp> struct remqual {using typ = ityp;};
template<typename ityp> struct remqual<ityp const> {using typ = ityp;};
template<typename ityp> struct remqual<ityp volatile> {using typ = ityp;};
template<typename ityp> struct remqual<ityp const volatile> {using typ = ityp;};
}
template<typename typ> using remqual = typename ::zap::impl::remqual<typ>::typ;
}
namespace zap {
namespace impl {
template<typename ltyp,typename rtyp> struct typeq {constexpr static bool eq = false;};
template<typename typ> struct typeq<typ,typ> {constexpr static auto eq = true;};
}
template<typename ltyp,typename rtyp> constexpr auto typeq = ::zap::impl::typeq<ltyp,rtyp>::eq;
}
namespace zap {
template<typename typ> constexpr auto ischrtyp =
::zap::typeq<typ,char>
|| ::zap::typeq<typ,char16_t>
|| ::zap::typeq<typ,char32_t>
#if __cpp_char8_t
|| ::zap::typeq<typ,char8_t>
#endif
|| ::zap::typeq<typ,unsigned char>
|| ::zap::typeq<typ,wchar_t>;
template<typename typ> constexpr auto isflttyp =
::zap::typeq<typ,double>
|| ::zap::typeq<typ,float>
|| ::zap::typeq<typ,long double>
#if __STDCPP_BFLOAT16_T__
|| ::zap::typeq<typ,decltype (0x0.0p0bf16)>
#endif
#if __STDCPP_FLOAT128_T__
|| ::zap::typeq<typ,decltype (0x0.0p0f16)>
#endif
#if __STDCPP_FLOAT16_T__
|| ::zap::typeq<typ,decltype (0x0.0p0f32)>
#endif
#if __STDCPP_FLOAT32_T__
|| ::zap::typeq<typ,decltype (0x0.0p0f64)>
#endif
#if __STDCPP_FLOAT64_T__
|| ::zap::typeq<typ,decltype (0x0.0p0f128)>
#endif
;
template<typename typ> constexpr auto isinttyp =
::zap::typeq<typ,int>
|| ::zap::typeq<typ,long>
|| ::zap::typeq<typ,long long>
|| ::zap::typeq<typ,short>
|| ::zap::typeq<typ,signed char>
|| ::zap::typeq<typ,unsigned char>
|| ::zap::typeq<typ,unsigned int>
|| ::zap::typeq<typ,unsigned long>
|| ::zap::typeq<typ,unsigned long long>
|| ::zap::typeq<typ,unsigned short>;
template<typename typ> constexpr auto isarithtyp =
::zap::isflttyp<typ>
|| ::zap::isinttyp<typ>;
}
namespace zap {
using i8 = ::zap_i8;
using i8s = ::zap_i8s;
using i01 = ::zap_i01;
using i01s = ::zap_i01s;
using i02 = ::zap_i02;
using i02s = ::zap_i02s;
using i04 = ::zap_i04;
using i04s = ::zap_i04s;
using ptr = ::zap_ptr;
using sz = ::zap_sz;
#if zap_fixflt02
using f02 = ::zap_f02;
#endif
#if zap_fixflt04
using f04 = ::zap_f04;
#endif
}
namespace zap {
constexpr auto ver = zap_ver;
constexpr auto bytelen = zap_bytelen;
constexpr auto nopos = zap_nopos;
}
namespace zap {
[[noreturn]] zap_attr_iln inline void trap() noexcept {::zap_trap();}
[[noreturn]] zap_attr_iln inline void unreach() noexcept {zap_unreach();}
}
#endif