Skip to content

Commit

Permalink
refactor: cleanup api
Browse files Browse the repository at this point in the history
  • Loading branch information
Curve committed Oct 18, 2024
1 parent 2c13a39 commit 3bcef7c
Show file tree
Hide file tree
Showing 8 changed files with 267 additions and 389 deletions.
4 changes: 2 additions & 2 deletions cmake/cpm.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
#
# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors

set(CPM_DOWNLOAD_VERSION 0.40.1)
set(CPM_HASH_SUM "117cbf2711572f113bab262933eb5187b08cfc06dce0714a1ee94f2183ddc3ec")
set(CPM_DOWNLOAD_VERSION 0.40.2)
set(CPM_HASH_SUM "c8cdc32c03816538ce22781ed72964dc864b2a34a310d3b7104812a5ca2d835d")

if(CPM_SOURCE_CACHE)
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
Expand Down
53 changes: 53 additions & 0 deletions include/rebind/core.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#pragma once

#include <string_view>
#include <source_location>

namespace rebind::impl
{
template <auto I>
using constant = std::integral_constant<decltype(I), I>;

template <auto T>
consteval std::string_view mangled_name()
{
return std::source_location::current().function_name();
}

template <typename U>
consteval auto unmangle(std::string_view name, U decorators)
{
const auto start = name.substr(name.rfind(decorators.first) + decorators.first.size());
const auto end = start.substr(0, start.rfind(decorators.second));

return end;
}

template <typename... Ts>
consteval auto remove_prefix(std::string_view name, Ts &&...prefixes)
{
const auto has_prefix = (name.starts_with(prefixes) || ...);

if (!has_prefix)
{
return name;
}

return name.substr(name.find(' ') + 1);
}

consteval auto remove_type(std::string_view name, std::string_view type, std::string_view delim)
{
const auto start = name.substr(name.rfind(type) + type.size());
const auto end = start.rfind(delim);

if (end == std::string_view::npos)
{
return std::string_view{};
}
else
{
return start.substr(end + delim.size());
}
}
} // namespace rebind::impl
138 changes: 46 additions & 92 deletions include/rebind/enum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,134 +2,88 @@

#include "name.hpp"

#include <array>
#include <tuple>
#include <cmath>
#include <limits>

#include <array>
#include <optional>
#include <algorithm>
#include <cstdint>
#include <limits>

namespace rebind
{
template <typename T>
requires std::is_enum_v<T>
static constexpr std::underlying_type_t<T> enum_find_min = 0;
static constexpr auto search_min = []
{
using underlying = std::underlying_type_t<T>;
constexpr auto limit = std::numeric_limits<underlying>::min();
return static_cast<underlying>(std::max(static_cast<std::int64_t>(limit), static_cast<std::int64_t>(-128)));
}();

template <typename T>
requires std::is_enum_v<T>
static constexpr std::underlying_type_t<T> enum_find_max =
std::min(std::numeric_limits<std::underlying_type_t<T>>::max(), static_cast<std::underlying_type_t<T>>(128));
static constexpr auto search_max = []
{
using underlying = std::underlying_type_t<T>;
constexpr auto limit = std::numeric_limits<underlying>::max();
return static_cast<underlying>(std::min(static_cast<std::uint64_t>(limit), static_cast<std::uint64_t>(128)));
}();

namespace impl
{
template <typename T>
requires std::is_enum_v<T>
struct enum_field
{
T value;
std::string_view name;
};

template <auto T>
requires std::is_enum_v<decltype(T)>
consteval auto enum_name()
{
return extract_member<T, decltype(T)>();
}
concept is_enum_value = std::is_enum_v<decltype(T)>;

template <auto T>
requires std::is_enum_v<decltype(T)>
consteval auto is_valid()
requires is_enum_value<T>
static constexpr auto enum_name = []
{
return !enum_name<T>().empty();
}
constexpr auto name = rebind::nttp_name<T>;
constexpr auto type = rebind::type_name<decltype(T)>;

template <typename T, auto I = enum_find_min<T>, auto R = 0>
requires std::is_enum_v<T>
consteval std::size_t valid_indices()
return remove_type(name, type, "::");
}();

template <typename T, auto I, auto Max, typename State>
consteval auto search_enum_values()
{
if constexpr (I < enum_find_max<T>)
if constexpr (I < Max)
{
if constexpr (is_valid<static_cast<T>(I)>())
constexpr auto value = static_cast<T>(I);
constexpr auto valid = !enum_name<value>.empty();

if constexpr (valid)
{
return valid_indices<T, I + 1, R + 1>();
constexpr auto new_state = std::tuple_cat(State{}, std::tuple{constant<value>{}});
return search_enum_values<T, I + 1, Max, decltype(new_state)>();
}
else
{
return valid_indices<T, I + 1, R>();
return search_enum_values<T, I + 1, Max, State>();
}
}

return R;
}

template <typename T, auto I = enum_find_min<T>, auto C = 0>
requires std::is_enum_v<T>
consteval void populate(auto &rtn)
{
constexpr auto value = static_cast<T>(I);

if constexpr (I < enum_find_max<T>)
else
{
if constexpr (is_valid<value>())
{
rtn[I] = enum_field<T>{
.value = value,
.name = enum_name<value>(),
};

return populate<T, I + 1, C + 1>(rtn);
}
else
{
return populate<T, I + 1, C>(rtn);
}
return State{};
}
}

template <typename T>
requires std::is_enum_v<T>
consteval auto enum_fields()
static constexpr auto enum_values = []
{
std::array<enum_field<T>, valid_indices<T>()> rtn;
populate<T>(rtn);
return rtn;
}
constexpr auto unpack = []<auto... Is>(std::tuple<constant<Is>...>)
{
return std::array<T, sizeof...(Is)>{static_cast<T>(Is)...};
};

return unpack(search_enum_values<T, search_min<T>, search_max<T>, std::tuple<>>());
}();
} // namespace impl

template <auto T>
static constexpr auto enum_name = impl::enum_name<T>();

template <typename T>
static constexpr auto enum_fields = impl::enum_fields<T>();
static constexpr auto enum_name = impl::enum_name<T>;

template <typename T>
requires std::is_enum_v<T>
constexpr std::optional<std::string_view> find_enum_name(T value)
{
constexpr auto fields = enum_fields<T>;
const auto rtn = std::ranges::find_if(fields, [&](auto &&x) { return x.value == value; });

if (rtn == fields.end())
{
return std::nullopt;
}

return rtn->name;
}

template <typename T>
requires std::is_enum_v<T>
constexpr std::optional<T> find_enum_value(std::string_view name)
{
constexpr auto fields = enum_fields<T>;
const auto rtn = std::ranges::find_if(fields, [&](auto &&x) { return x.name == name; });

if (rtn == fields.end())
{
return std::nullopt;
}

return rtn->value;
}
static constexpr auto enum_values = impl::enum_values<T>;
} // namespace rebind
Loading

0 comments on commit 3bcef7c

Please sign in to comment.