Created
March 2, 2020 02:32
-
-
Save bjadamson/898392bb2ed27107817076a13701a319 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace | |
{ | |
std::optional<std::string_view> | |
get_stringview(std::string_view const& sv, toml::table const& table) | |
{ | |
auto const node = table[sv]; | |
if (!node) { | |
return std::nullopt; | |
} | |
assert(node.is_string()); | |
return node.as_string()->get(); | |
} | |
toml::array const* | |
get_array(std::string_view const& sv, toml::table const& table) | |
{ | |
auto const& node = table[sv]; | |
if (!node) { | |
return nullptr; | |
} | |
assert(node.is_array()); | |
return node.as_array(); | |
} | |
template <typename T> | |
std::optional<T> | |
get_floating_point(std::string_view const& sv, toml::table const& table) | |
{ | |
auto const& node = table[sv]; | |
if (!node) { | |
return std::nullopt; | |
} | |
assert(node.is_floating_point()); | |
auto const fp = node.as_floating_point()->get(); | |
return static_cast<T>(fp); | |
} | |
template <typename R, typename FN, typename T, T... ints> | |
auto constexpr from_sequence(FN const& fn, std::integer_sequence<T, ints...>) | |
{ | |
size_t i = 0; | |
R arr; | |
((arr[i++] = fn(ints)), ...); | |
// TODO: ? R{{(fn(ints), ...)}}; | |
return arr; | |
} | |
template <typename T, size_t N, typename R> | |
std::optional<R> | |
get_array_n(std::string_view const& name, toml::table const& table) | |
{ | |
static_assert(N > 0, "n must be >0"); | |
auto const nview = table[name]; | |
if (!nview) { | |
return std::nullopt; | |
} | |
assert(nview.is_array()); | |
auto const& arr = *nview.as_array(); | |
assert(arr.is_homogeneous()); | |
assert(arr.size() == N); | |
assert(arr[0].is_number()); | |
using itype = typename toml::array::size_type; | |
if constexpr (std::is_floating_point_v<T>) { | |
assert(arr[0].is_floating_point()); | |
auto const as_fp = [&](itype const i) { return static_cast<T>(arr[i].as_floating_point()->get()); }; | |
return from_sequence<R>(as_fp, std::make_integer_sequence<itype, N>{}); | |
} | |
else if constexpr (std::is_integral_v<T>) { | |
auto const as_int = [&](itype const i) { return static_cast<T>(arr[i].as_integer()->get()); }; | |
return from_sequence<R>(as_int, std::make_integer_sequence<itype, N>{}); | |
} | |
else { | |
static_assert(always_false<T>, "only floating-point and integral types are supported."); | |
} | |
} | |
template <typename T> | |
auto constexpr get_array3 = get_array_n<T, 3, std::array<T, 3>>; | |
template <typename T> | |
auto constexpr get_array4 = get_array_n<T, 4, std::array<T, 4>>; | |
template <typename T> | |
auto constexpr get_vec3 = get_array_n<T, 3, glm::vec3>; | |
template <typename T> | |
auto constexpr get_vec4 = get_array_n<T, 4, glm::vec4>; | |
std::optional<bool> | |
get_bool(std::string_view const& name, toml::table const& table) | |
{ | |
auto const nview = table[name]; | |
if (!nview) { | |
return std::nullopt; | |
} | |
assert(nview.is_boolean()); | |
return nview.as_boolean()->get(); | |
} | |
std::optional<int64_t> | |
get_int64(std::string_view const& name, toml::table const& table) | |
{ | |
auto const nview = table[name]; | |
if (!nview) { | |
return std::nullopt; | |
} | |
assert(nview.is_integer()); | |
return nview.as_integer()->get(); | |
} | |
} // namespace | |
namespace | |
{ | |
template <auto fn> | |
auto const& | |
get_or_abort_ref(std::string_view const& sv, toml::table const& table) | |
{ | |
auto const opt = fn(sv, table); | |
assert(opt); | |
return *opt; | |
} | |
template <auto fn> | |
auto | |
get_or_abort(std::string_view const& sv, toml::table const& table) | |
{ | |
auto const opt = fn(sv, table); | |
assert(opt); | |
return *opt; | |
} | |
auto constexpr get_string_or_abort = get_or_abort<get_stringview>; | |
auto constexpr get_array_or_abort = get_or_abort_ref<get_array>; | |
template <typename T> | |
auto constexpr get_floating_point_or_abort = get_or_abort<get_floating_point<T>>; | |
template <typename T> | |
auto constexpr get_array3_or_abort = get_or_abort<get_array3<T>>; | |
template <typename T> | |
auto constexpr get_vec3_or_abort = get_or_abort<get_vec3<T>>; | |
template <typename T> | |
auto constexpr get_array4_or_abort = get_or_abort<get_array4<T>>; | |
auto constexpr get_int64_or_abort = get_or_abort<get_int64>; | |
template <typename T> | |
auto constexpr get_vec4_or_abort = get_or_abort<get_vec4<T>>; | |
auto constexpr get_bool_or_abort = get_or_abort<get_bool>; | |
} // namespace |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment