是否可以在编译时将字符串转换为大写而没有任何大小限制?
例如:
char* myString = TO_UPPERCASE("a big string here!");
会生成:
char* myString = "A BIG STRING HERE!";
答案 0 :(得分:1)
可以使用Boost.Hana和C ++ 14。
#include <iostream>
#include <boost/hana/unpack.hpp>
#include <boost/hana/string.hpp>
#include <boost/hana/integral_constant.hpp>
#include <boost/hana/value.hpp>
#include <boost/hana/core/to.hpp>
constexpr char to_upper(char c) noexcept
{
switch(c) {
default: return c;
case 'b': return 'B';
case 'i': return 'I';
case 'g': return 'G';
case 's': return 'S';
case 't': return 'T';
case 'r': return 'R';
case 'n': return 'N';
// The other characters in the alphabet.
}
}
auto to_upper_str = [](auto hana_str) noexcept {
return boost::hana::unpack(hana_str, [](auto... chars) noexcept {
return boost::hana::string_c<
boost::hana::char_c<to_upper(boost::hana::value(chars))>...>;
});
};
int main()
{
auto str = to_upper_str(BOOST_HANA_STRING("Big string."));
std::cout << boost::hana::to<const char*>(str) << '\n';
}
此输出BIG STRING.
请参阅Coliru。
答案 1 :(得分:0)
只要您不想尝试将字符串链直接传递给模板,并创建辅助变量来存储此序列,以便进一步使用此代码(c ++ 1z):
#include <utility>
#include <iostream>
#include <type_traits>
#include <typeinfo>
template <class T>
struct string_literal_length;
template <std::size_t N>
struct string_literal_length<char const[N]>{
static constexpr std::size_t value = N;
};
template <class STR_T, STR_T &, class = std::make_index_sequence<string_literal_length<STR_T>::value>>
struct string_literal;
template <class STR_T, STR_T &STR, std::size_t... Is>
struct string_literal<STR_T, STR, std::index_sequence<Is...>> {
static constexpr std::size_t size = string_literal_length<STR_T>::value;
static constexpr char value[string_literal_length<STR_T>::value] = {STR[Is]...};
};
constexpr char str[] = "abc";
template <class SL, class = std::make_index_sequence<SL::size>>
struct string_literal_to_upper;
template <class SL, std::size_t... Is>
struct string_literal_to_upper<SL, std::index_sequence<Is...>>{
static constexpr char value[SL::size] = { ((SL::value[Is] >= 'a' && SL::value[Is] <= 'z')?(static_cast<char>(SL::value[Is] - 'a' + 'A')):(SL::value[Is]))...};
};
int main() {
std::cout << string_literal_to_upper<string_literal<decltype(str), str>>::value << std::endl;
}
输出:
ABC
修改强>
要在VS中工作,代码需要稍微修改一下:
#include <utility>
#include <iostream>
#include <type_traits>
#include <typeinfo>
template <class T>
struct string_literal_length;
template <std::size_t N>
struct string_literal_length<char const[N]>{
static constexpr std::size_t value = N;
};
template <class STR_T, STR_T *, class = std::make_index_sequence<string_literal_length<STR_T>::value>>
struct string_literal;
template <class STR_T, STR_T *STR, std::size_t... Is>
struct string_literal<STR_T, STR, std::index_sequence<Is...>> {
static constexpr std::size_t size = string_literal_length<STR_T>::value;
static constexpr char value[string_literal_length<STR_T>::value] = { (*STR)[Is]...};
};
struct Literal {
static constexpr char const str[] = "abc";
};
template <class SL, class = std::make_index_sequence<SL::size>>
struct string_literal_to_upper;
template <class SL, std::size_t... Is>
struct string_literal_to_upper<SL, std::index_sequence<Is...>>{
static constexpr char value[SL::size] = { ((SL::value[Is] >= 'a' && SL::value[Is] <= 'z')?(static_cast<char>(SL::value[Is] - 'a' + 'A')):(SL::value[Is]))...};
};
int main() {
std::cout << string_literal_to_upper<string_literal<decltype(Literal::str), &Literal::str>>::value << std::endl;
}