Add support for int_conv<std::array>()

This commit is contained in:
King_DuckZ 2021-05-29 16:47:48 +02:00
parent 938c8fa9a4
commit 199db7640e
3 changed files with 51 additions and 0 deletions

View file

@ -26,6 +26,7 @@
# include <string>
# include <sstream>
#endif
#include <tuple>
namespace dhandy {
template <typename T, std::size_t S>
@ -33,6 +34,8 @@ namespace dhandy {
static_assert(S > 0, "This container requires size to be at least 1");
static_assert(std::is_trivial<T>::value, "Only use this container with trivial types");
public:
constexpr static const std::size_t capacity = S;
using iterator = typename std::array<T, S>::iterator;
constexpr ReversedSizedArray() = default;
~ReversedSizedArray() = default;
@ -49,6 +52,7 @@ namespace dhandy {
template <typename V>
constexpr V to() const { return V(data(), size() - (not empty() and not back() ? 1 : 0)); }
constexpr auto to_tuple() const;
#if !defined(INT_CONV_WITHOUT_HELPERS)
constexpr std::basic_string_view<T> to_string_view() const { return to<std::basic_string_view<T>>(); }
@ -65,6 +69,13 @@ namespace dhandy {
std::size_t m_curr {S - 1};
};
namespace implem {
template <typename T, std::size_t S, std::size_t... Indices>
constexpr auto elements_or_empty_to_tuple (const std::array<T, S>& elems, std::size_t from_idx, std::index_sequence<Indices...>) {
return std::make_tuple((from_idx + Indices < S ? elems[from_idx + Indices] : T{})...);
}
} //namespace implem
#if !defined(INT_CONV_WITHOUT_HELPERS)
template <typename T, std::size_t S>
inline
@ -73,6 +84,11 @@ namespace dhandy {
return stream;
}
#endif
template <typename T, std::size_t S>
constexpr auto ReversedSizedArray<T, S>::to_tuple() const {
return implem::elements_or_empty_to_tuple(m_data, m_curr + 1, std::make_index_sequence<S>{});
}
} //namespace dhandy
#endif

View file

@ -22,6 +22,7 @@
#include <type_traits>
#include <string>
#include <string_view>
#include <array>
namespace dhandy {
namespace implem {
@ -47,6 +48,23 @@ namespace dhandy {
return dhandy::int_to_ary<F, 10, Tr>(in).to_string_view();
}
};
template <typename F, typename Tr, typename C, std::size_t N>
struct IntConv<std::array<C, N>, F, Tr, true> {
private:
template <typename... Args, std::size_t... Indices>
constexpr static std::array<C, N> to_array (const std::tuple<Args...>& vals, std::index_sequence<Indices...>) {
return std::array<C, N>{std::get<Indices>(vals)...};
}
public:
constexpr static std::array<C, N> conv (const F& in) {
return to_array(
dhandy::int_to_ary<F, 10, Tr>(in).to_tuple(),
std::make_index_sequence<
std::min(decltype(dhandy::int_to_ary<F, 10, Tr>(in))::capacity, N)
>{}
);
}
};
template <typename T, typename Tr>
struct IntConv<T, IntConvString<Tr>, Tr, false> {
constexpr static T conv (const IntConvString<Tr>& in) {

View file

@ -224,6 +224,23 @@ TEST_CASE ("Check string_view conversions work as expected", "[i2s][int_conv]")
CHECK("123" == str123);
}
TEST_CASE ("Check std::array conversion works as expected", "[i2s][int_conv]") {
using std::array;
using dhandy::int_conv;
auto arr748 = int_conv<array<char, 3>>(748);
CHECK(arr748[0] == '7');
CHECK(arr748[1] == '4');
CHECK(arr748[2] == '8');
auto arr19000 = int_conv<array<char, 5>>(19);
CHECK(arr19000[0] == '1');
CHECK(arr19000[1] == '9');
CHECK(arr19000[2] == '\0');
CHECK(arr19000[3] == '\0');
CHECK(arr19000[4] == '\0');
}
TEST_CASE ("Check upcase/downcase int to array conversions", "[i2s][int_conv]") {
using dhandy::int_conv;
using std::string_view;