c++ - Convert `hana::string` to `constexpr const char (&)[]` -
i have old code uses similar str_const
described here , here constexpr string manipulation. str_const
literal type described scott schurr can constructed string literal, because has template constructor const char (&)[]
.
i have new code using boost::hana
.
i able take hana::string
, create str_const
refers it. simplest way convert hana::string
constexpr const char (&)[]
. (actually, @ point that's not simplest way, simplest way surely add new template constructor str_const
implementation. @ point question has taken on life of it's own , i'm interested in whether can done hana::string
. let's assume i'm not allowed change str_const
implementation.)
however, in hana
docs way convert hana::string
run-time string hana::to<const char *>
.
optimistically, tried various forms of hana::to<const char (&)[hana::length(...)]> (...)
causes static assertions in hana
fail.
the other option suggested hana
docs use hana::unpack
, stick characters in array myself. wrote code
template <typename t, size_t n> struct array { t arr[n]; }; struct char_packer { template <typename... ts> constexpr auto operator()(ts... ts) -> array<const char, sizeof...(ts) + 1> { return array<const char, sizeof...(ts) + 1>{{ ts... , 0 }}; } }; template <typename s> struct string_keeper { static constexpr auto my_array = hana::unpack(s{}, char_packer{}); }; template <int n> using char_arr = const char [n]; template <typename s> constexpr auto to_string_literal(s &&) -> const char_arr<decltype(hana::length(s{}))::value + 1> & { return string_keeper<s>::my_array.arr; }
i think works, @ least compiles. if references used @ run-time fails linker error: undefined reference ... string_keeper<boost::hana::string<(char)97> >::my_array
.
(actually think understand why that's odr problem , if think on bit longer might remember how fix it... not sure...)
intuitively, feel there must way this. because, hana
allows me convert hana::string
constexpr const char *
pointer points array want. in fact suggests there's might evil option try coerce const char *
(&)[]
type, although seems require doing things won't allowed in constexpr
functions. anyways if hana
can make array surely can too, or somehow convince give me more exactly.
is there way fix code above? there easier way within hana
overlooked? impossible reason?
one other problem that, when returned function, raw char array decayed pointer. suggest constructing str_const
object in context of function believe fulfills intent of creating str_const
without changing interface.
the following example uses top level variable template create array hana::string
implementation uses:
#define boost_hana_config_enable_string_udl #include <boost/hana.hpp> #include <stdexcept> namespace hana = boost::hana; using namespace hana::literals; class str_const { const char * const p_; const std::size_t sz_; public: template <std::size_t n> constexpr str_const( const char( & )[ n ] ) : p_( ), sz_( n - 1 ) {} constexpr char operator[]( std::size_t n ) const { return n < sz_ ? p_[ n ] : throw std::out_of_range( "" ); } constexpr std::size_t size() const { return sz_; } }; template <char ...c> constexpr char string_storage[sizeof...(c) + 1] = {c..., '\0'}; struct to_str_const_helper { template <typename ...ts> constexpr auto operator()(ts...) { return str_const(string_storage<ts::value...>); } }; template <typename s> constexpr auto to_str_const(s) { return hana::unpack(s{}, to_str_const_helper{}); } int main() { constexpr str_const str = to_str_const("foo"_s); static_assert(str[0] == 'f', ""); static_assert(str[1] == 'o', ""); static_assert(str[2] == 'o', ""); }
Comments
Post a Comment