refactor: dimension_symbol and units_symbol refactored to use inplace_vector

This commit is contained in:
Mateusz Pusz
2024-07-03 22:57:50 +01:00
parent 6f03c04d97
commit c59ab3e11e
2 changed files with 18 additions and 64 deletions

View File

@@ -28,6 +28,7 @@
#include <mp-units/bits/text_tools.h>
#include <mp-units/compat_macros.h>
#include <mp-units/ext/fixed_string.h>
#include <mp-units/ext/inplace_vector.h>
#include <mp-units/ext/type_traits.h>
#include <mp-units/framework/dimension_concepts.h>
#include <mp-units/framework/expression_template.h>
@@ -301,47 +302,23 @@ constexpr Out dimension_symbol_to(Out out, D d, const dimension_symbol_formattin
return detail::dimension_symbol_impl<CharT>(out, d, fmt, false);
}
namespace detail {
template<typename CharT, std::size_t N, dimension_symbol_formatting fmt, Dimension D>
[[nodiscard]] consteval std::array<CharT, N> get_symbol_buffer(D)
{
std::array<CharT, N> buffer{};
dimension_symbol_to<CharT>(buffer.begin(), D{}, fmt);
return buffer;
}
} // namespace detail
// TODO Refactor to `dimension_symbol(D, fmt)` when P1045: constexpr Function Parameters is available
MP_UNITS_EXPORT template<dimension_symbol_formatting fmt = dimension_symbol_formatting{}, typename CharT = char,
Dimension D>
#if defined MP_UNITS_COMP_CLANG && MP_UNITS_COMP_CLANG <= 18
[[nodiscard]] constexpr auto dimension_symbol(D)
#else
[[nodiscard]] consteval auto dimension_symbol(D)
#endif
{
auto get_size = []() consteval {
#if MP_UNITS_HOSTED
std::basic_string<CharT> buffer;
dimension_symbol_to<CharT>(std::back_inserter(buffer), D{}, fmt);
return buffer.size();
#else
std::array<CharT, 128> buffer; // TODO unsafe
auto end = dimension_symbol_to<CharT>(buffer.begin(), D{}, fmt);
return end - buffer.begin();
#endif
auto get_symbol_text = []() consteval {
detail::inplace_vector<CharT, 64> text; // TODO can we improve here?
dimension_symbol_to<CharT>(std::back_inserter(text), D{}, fmt);
return text;
};
constexpr auto text = get_symbol_text();
#if MP_UNITS_API_STRING_VIEW_RET // Permitting static constexpr variables in constexpr functions
static constexpr std::size_t size = get_size();
static constexpr auto buffer = detail::get_symbol_buffer<CharT, size, fmt>(D{});
return std::string_view(buffer.data(), size);
static constexpr basic_fixed_string<CharT, text.size()> buffer(std::from_range, text);
return buffer.view();
#else
constexpr std::size_t size = get_size();
return basic_fixed_string(std::from_range, detail::get_symbol_buffer<CharT, size, fmt>(D{}));
return basic_fixed_string<CharT, text.size()>(std::from_range, text);
#endif
}

View File

@@ -31,6 +31,7 @@
#include <mp-units/compat_macros.h>
#include <mp-units/ext/algorithm.h>
#include <mp-units/ext/fixed_string.h>
#include <mp-units/ext/inplace_vector.h>
#include <mp-units/ext/type_name.h>
#include <mp-units/ext/type_traits.h>
#include <mp-units/framework/expression_template.h>
@@ -813,46 +814,22 @@ constexpr Out unit_symbol_to(Out out, U u, const unit_symbol_formatting& fmt = u
return detail::unit_symbol_impl<CharT>(out, u, fmt, false);
}
namespace detail {
template<typename CharT, std::size_t N, unit_symbol_formatting fmt, Unit U>
[[nodiscard]] consteval std::array<CharT, N> get_symbol_buffer(U)
{
std::array<CharT, N> buffer{};
unit_symbol_to<CharT>(buffer.begin(), U{}, fmt);
return buffer;
}
} // namespace detail
// TODO Refactor to `unit_symbol(U, fmt)` when P1045: constexpr Function Parameters is available
MP_UNITS_EXPORT template<unit_symbol_formatting fmt = unit_symbol_formatting{}, typename CharT = char, Unit U>
#if defined MP_UNITS_COMP_CLANG && MP_UNITS_COMP_CLANG <= 18
[[nodiscard]] constexpr auto unit_symbol(U)
#else
[[nodiscard]] consteval auto unit_symbol(U)
#endif
{
auto get_size = []() consteval {
#if MP_UNITS_HOSTED
std::basic_string<CharT> buffer;
unit_symbol_to<CharT>(std::back_inserter(buffer), U{}, fmt);
return buffer.size();
#else
std::array<CharT, 128> buffer; // TODO unsafe
auto end = unit_symbol_to<CharT>(buffer.begin(), U{}, fmt);
return end - buffer.begin();
#endif
auto get_symbol_text = []() consteval {
detail::inplace_vector<CharT, 64> text; // TODO can we improve here?
unit_symbol_to<CharT>(std::back_inserter(text), U{}, fmt);
return text;
};
constexpr auto text = get_symbol_text();
#if MP_UNITS_API_STRING_VIEW_RET // Permitting static constexpr variables in constexpr functions
static constexpr std::size_t size = get_size();
static constexpr auto buffer = detail::get_symbol_buffer<CharT, size, fmt>(U{});
return std::string_view(buffer.data(), size);
static constexpr basic_fixed_string<CharT, text.size()> buffer(std::from_range, text);
return buffer.view();
#else
constexpr std::size_t size = get_size();
return basic_fixed_string(std::from_range, detail::get_symbol_buffer<CharT, size, fmt>(U{}));
return basic_fixed_string<CharT, text.size()>(std::from_range, text);
#endif
}