based

Opinionated utility library
git clone git://git.dimitrijedobrota.com/based.git
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING

commit 7083865ed7f62a4e3c428ecd93da9fd611c58a9f
parent de0eccb93776d7f47e26fdb03b589a23e80b439e
author Dimitrije Dobrota < mail@dimitrijedobrota.com >
date Mon, 16 Jun 2025 18:57:19 +0200

Simplify integral literals implementation

* No need to go custom just yet

Diffstat:
M include/based/types/literals.hpp | +++++++++++++++ -------------------------------------------------------------------

1 files changed, 21 insertions(+), 97 deletions(-)


diff --git a/ include/based/types/literals.hpp b/ include/based/types/literals.hpp

@@ -1,7 +1,5 @@

#pragma once

#include "based/char/is/digit.hpp"
#include "based/concepts/is/castable.hpp"
#include "based/types/types.hpp"

// NOLINTBEGIN(google-runtime-int)

@@ -9,144 +7,70 @@

namespace based
{

// Signed
namespace detail
{

template<signed long long val>
consteval i make_signed_itnernal()
{
return i::underlying_cast(val);
}

template<signed long long v, char c, char... cs>
consteval auto make_signed_itnernal()
{
const signed long long radix = 10;

static_assert(is_digit(character(c)), "invalid digit");
static_assert(v <= (limits<i64>::max.value - (c - '0')) / radix, "overflow");

return make_signed_itnernal<(radix * v) + (c - '0'), cs...>();
}

template<char... cs>
consteval auto make_signed()
{
return make_signed_itnernal<0, cs...>();
}

} // namespace detail

namespace literals
{

template<char... cs>
consteval auto operator"" _i()
consteval auto operator""_i(unsigned long long val)
{
return detail::make_signed<cs...>();
return i::underlying_cast(val);
}

template<char... cs>
requires CastableTo<decltype(detail::make_signed<cs...>()), u8>
consteval auto operator"" _i8()
consteval i8 operator""_i8(unsigned long long val)
{
return i8::cast(detail::make_signed<cs...>());
return i::underlying_cast(val);
}

template<char... cs>
requires CastableTo<decltype(detail::make_signed<cs...>()), u16>
consteval auto operator"" _i16()
consteval i16 operator""_i16(unsigned long long val)
{
return i16::cast(detail::make_signed<cs...>());
return i::underlying_cast(val);
}

template<char... cs>
requires CastableTo<decltype(detail::make_signed<cs...>()), u32>
consteval auto operator"" _i32()
consteval i32 operator""_i32(unsigned long long val)
{
return i32::cast(detail::make_signed<cs...>());
return i::underlying_cast(val);
}

template<char... cs>
requires CastableTo<decltype(detail::make_signed<cs...>()), u64>
consteval auto operator"" _i64()
consteval i64 operator""_i64(unsigned long long val)
{
return i64::cast(detail::make_signed<cs...>());
return i::underlying_cast(val);
}

} // namespace literals

// Unsigned

namespace detail
{

template<unsigned long long val>
consteval u make_unsigned_internal()
{
return u::underlying_cast(val);
}

template<unsigned long long v, char c, char... cs>
consteval auto make_unsigned_internal()
{
const unsigned long long radix = 10;

static_assert(is_digit(character(c)), "invalid digit");
static_assert(v <= (limits<u64>::max.value - (c - '0')) / radix, "overflow");

return make_unsigned_internal<(radix * v) + c - '0', cs...>();
}

template<char... cs>
consteval auto make_unsigned()
{
return make_unsigned_internal<0, cs...>();
}

} // namespace detail

namespace literals
{

template<char... cs>
consteval auto operator"" _u()
consteval auto operator""_u(unsigned long long val)
{
return detail::make_unsigned<cs...>();
return u::underlying_cast(val);
}

template<char... cs>
requires CastableTo<decltype(detail::make_unsigned<cs...>()), u8>
consteval auto operator"" _u8()
consteval u8 operator""_u8(unsigned long long val)
{
return u8::cast(detail::make_unsigned<cs...>());
return u::underlying_cast(val);
}

template<char... cs>
requires CastableTo<decltype(detail::make_unsigned<cs...>()), u16>
consteval auto operator"" _u16()
consteval u16 operator""_u16(unsigned long long val)
{
return u16::cast(detail::make_unsigned<cs...>());
return u::underlying_cast(val);
}

template<char... cs>
requires CastableTo<decltype(detail::make_unsigned<cs...>()), u32>
consteval auto operator"" _u32()
consteval u32 operator""_u32(unsigned long long val)
{
return u32::cast(detail::make_unsigned<cs...>());
return u::underlying_cast(val);
}

template<char... cs>
requires CastableTo<decltype(detail::make_unsigned<cs...>()), u64>
consteval auto operator"" _u64()
consteval u64 operator""_u64(unsigned long long val)
{
return u64::cast(detail::make_unsigned<cs...>());
return u::underlying_cast(val);
}

} // namespace literals

using namespace literals; // NOLINT(*namespace*)

} // namespace based

// NOLINTEND(google-runtime-int)