/* Copyright 2018 kevin Lau (http://github.com/stormycatcat)

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#ifndef _STDLIB_CSTDDEF_
#define _STDLIB_CSTDDEF_

#include <sys/portable.h>

#ifndef NULL
#define NULL 0
#endif

#ifndef offsetof
#define offsetof(type,member) ((size_t)&(((type*)0)->member))
#endif

namespace std
{

#ifndef _SIZE_T
#define _SIZE_T
using size_t __mode__(__DI__) = unsigned long;
#endif

#ifndef _SSIZE_T
#define _SSIZE_T
using ssize_t __mode__(__DI__) = long;
#endif

#ifndef _PTRDIFF_T
#define _PTRDIFF_T
using ptrdiff_t __mode__(__DI__) = long;
#endif

#ifndef _NULLPTR_T
#define _NULLPTR_T
using nullptr_t=decltype(nullptr);
#endif

enum class byte : unsigned char {};


template<class T>
struct is_integral;

template <class IntegerType>
constexpr IntegerType to_integer(byte b) noexcept
{
    static_assert(is_integral<IntegerType>::value==false,"can't transfer to non-integral type");
    return IntegerType(b);
}

template <class IntegerType>
constexpr byte& operator<<=(byte& b, IntegerType shift) noexcept
{
    static_assert(is_integral<IntegerType>::value==false,"can't transfer to non-integral type");
    return b=byte(static_cast<unsigned char>(b)<<shift);
}

template <class IntegerType>
constexpr byte& operator>>=(byte& b, IntegerType shift) noexcept
{
    static_assert(is_integral<IntegerType>::value==false,"can't transfer to non-integral type");
    return b=byte(static_cast<unsigned char>(b)>>shift);
}

template <class IntegerType>
constexpr byte operator<<(byte& b, IntegerType shift) noexcept
{
    static_assert(is_integral<IntegerType>::value==false,"can't transfer to non-integral type");
    return byte(static_cast<unsigned char>(b)<<shift);
}

template <class IntegerType>
constexpr byte operator>>(byte& b, IntegerType shift) noexcept
{
    static_assert(is_integral<IntegerType>::value==false,"can't transfer to non-integral type");
    return byte(static_cast<unsigned char>(b)>>shift);
}

constexpr byte& operator|=(byte& l, byte r) noexcept
{
    return l=byte(static_cast<unsigned char>(l)|static_cast<unsigned char>(r));
}

constexpr byte& operator&=(byte& l, byte r) noexcept
{
    return l=byte(static_cast<unsigned char>(l)&static_cast<unsigned char>(r));
}

constexpr byte& operator^=(byte& l, byte r) noexcept
{
    return l=byte(static_cast<unsigned char>(l)^static_cast<unsigned char>(r));
}

constexpr byte operator|(byte l, byte r) noexcept
{
    return byte(static_cast<unsigned char>(l)|static_cast<unsigned char>(r));
}

constexpr byte operator&(byte l, byte r) noexcept
{
    return byte(static_cast<unsigned char>(l)&static_cast<unsigned char>(r));
}

constexpr byte operator^(byte l, byte r) noexcept
{
    return byte(static_cast<unsigned char>(l)^static_cast<unsigned char>(r));
}

constexpr byte operator~(byte b) noexcept
{
    return byte(~static_cast<unsigned char>(b));
}


}


#endif