如何反转 hana::string
How to reverse a hana::string
有谁知道如何反转 boost::hana::string?
以下不起作用:
#include <boost/hana.hpp>
#include <boost/hana/reverse.hpp>
auto s = BOOST_HANA_STRING("abc");
auto s2 = boost::hana::reverse(s);
错误信息:
boost/hana/reverse.hpp:36:9: error: static_assert failed due to requirement
'hana::Sequence<S>::value' "hana::reverse(xs)
requires 'xs' to be a Sequence"
In particular, one should not take for granted that the template parameters are chars. The proper way to access the contents of a hana::string as character constants is to use hana::unpack, .c_str() or hana::to
所以,我想看的方向是"how to transform a hana::string to a Sequence"
谢谢!
嗯,我不得不深入研究一下 hana 字符串的内部结构。
但是 Hana 非常实用,所以这个简短的解决方案就足够了:
auto reverse_boost_hana_string = [](auto s) {
auto add_reverse = [=](auto xs, auto ys) {
auto ys_s = boost::hana::string<ys>(); // this is what I had wrong for a while
return ys_s + xs;
};
auto reversed = boost::hana::fold_left(s, BOOST_HANA_STRING(""), add_reverse);
return reversed;
};
int main()
{
auto s = BOOST_HANA_STRING("abcdef");
auto s2 = reverse_boost_hana_string(s);
std::cout << "Reversed ==>" << s2.c_str() << "<==\n";
}
在没有模板噪音的情况下编写 TMP 非常令人愉快。
Boost.Hana 当然是函数式的,但是如果你能避免折叠类型,你可以获得一个编译时效率更高的算法。
#include <array>
#include <boost/hana.hpp>
namespace hana = boost::hana;
template <typename S, unsigned long ...i>
auto reverse_string_impl(S s, std::index_sequence<i...>) {
constexpr unsigned long n = sizeof...(i);
constexpr char const* c = hana::to<char const*>(s);
return hana::make_string(hana::char_c<c[n - i - 1]>...);
// would be better but assumes stuff about the impl of hana::string
//return hana::string<c[n - i - 1]...>{};
}
template <typename S>
constexpr auto reverse_string(S) {
return reverse_string_impl(S{},
std::make_index_sequence<hana::length(S{})>{});
}
int main() {
BOOST_HANA_CONSTANT_ASSERT(
BOOST_HANA_STRING("foo") == reverse_string(BOOST_HANA_STRING("oof"))
);
// or just convert to a tuple and back (less efficient)
BOOST_HANA_CONSTANT_ASSERT(
BOOST_HANA_STRING("foo") ==
hana::unpack(
hana::reverse(hana::unpack(BOOST_HANA_STRING("oof"),
hana::make_tuple)),
hana::make_string)
);
}
有谁知道如何反转 boost::hana::string?
以下不起作用:
#include <boost/hana.hpp>
#include <boost/hana/reverse.hpp>
auto s = BOOST_HANA_STRING("abc");
auto s2 = boost::hana::reverse(s);
错误信息:
boost/hana/reverse.hpp:36:9: error: static_assert failed due to requirement
'hana::Sequence<S>::value' "hana::reverse(xs)
requires 'xs' to be a Sequence"
In particular, one should not take for granted that the template parameters are chars. The proper way to access the contents of a hana::string as character constants is to use hana::unpack, .c_str() or hana::to
所以,我想看的方向是"how to transform a hana::string to a Sequence"
谢谢!
嗯,我不得不深入研究一下 hana 字符串的内部结构。
但是 Hana 非常实用,所以这个简短的解决方案就足够了:
auto reverse_boost_hana_string = [](auto s) {
auto add_reverse = [=](auto xs, auto ys) {
auto ys_s = boost::hana::string<ys>(); // this is what I had wrong for a while
return ys_s + xs;
};
auto reversed = boost::hana::fold_left(s, BOOST_HANA_STRING(""), add_reverse);
return reversed;
};
int main()
{
auto s = BOOST_HANA_STRING("abcdef");
auto s2 = reverse_boost_hana_string(s);
std::cout << "Reversed ==>" << s2.c_str() << "<==\n";
}
在没有模板噪音的情况下编写 TMP 非常令人愉快。
Boost.Hana 当然是函数式的,但是如果你能避免折叠类型,你可以获得一个编译时效率更高的算法。
#include <array>
#include <boost/hana.hpp>
namespace hana = boost::hana;
template <typename S, unsigned long ...i>
auto reverse_string_impl(S s, std::index_sequence<i...>) {
constexpr unsigned long n = sizeof...(i);
constexpr char const* c = hana::to<char const*>(s);
return hana::make_string(hana::char_c<c[n - i - 1]>...);
// would be better but assumes stuff about the impl of hana::string
//return hana::string<c[n - i - 1]...>{};
}
template <typename S>
constexpr auto reverse_string(S) {
return reverse_string_impl(S{},
std::make_index_sequence<hana::length(S{})>{});
}
int main() {
BOOST_HANA_CONSTANT_ASSERT(
BOOST_HANA_STRING("foo") == reverse_string(BOOST_HANA_STRING("oof"))
);
// or just convert to a tuple and back (less efficient)
BOOST_HANA_CONSTANT_ASSERT(
BOOST_HANA_STRING("foo") ==
hana::unpack(
hana::reverse(hana::unpack(BOOST_HANA_STRING("oof"),
hana::make_tuple)),
hana::make_string)
);
}