#ifndef STD_BIT_H
#define STD_BIT_H

#include <type_traits>

namespace std {

    template<class ToType, class FromType>
	constexpr ToType bit_cast(FromType const& from) noexcept 
		requires(sizeof(ToType) == sizeof(FromType) &&
				 is_trivially_copyable_v<ToType> &&
				 is_trivially_copyable_v<FromType>)
	{
        return __builtin_bit_cast(ToType, from);
    }

	template<typename T>
	constexpr int countl_zero(T x) noexcept
	{
		return __builtin_clz(static_cast<unsigned int>(x));
	}

	template<typename T>
	constexpr int countl_one(T x) noexcept
	{
		return countl_zero(~x);
	}

	template<typename T>
	constexpr int countr_zero(T x) noexcept
	{
		return __builtin_ctz(static_cast<unsigned int>(x));
	}

	template <typename T>
	constexpr bool has_single_bit(T x) noexcept
	{
		return x != 0 && (x & (x - 1)) == 0;
	}
}

#endif