コンパイル時toupperとtolower
見たまんまですね。
文字列リテラル又はsprout::stringから処理を施したsprout::stringを生成します。
C++1yならdecltypeの部分は無くても動きますが、C++11対応のため。
#include <type_traits> #include <sprout/string.hpp> #include <sprout/index_tuple.hpp> template<class T, std::size_t size, sprout::index_t... indexes> constexpr auto toupper_impl(const T (&str)[size], sprout::index_tuple<indexes...>) -> decltype( sprout::make_string(static_cast<char>('a' <= str[indexes] && str[indexes] <= 'z' ? str[indexes] - ('a' - 'A') : str[indexes])...) ) { return sprout::make_string(static_cast<char>('a' <= str[indexes] && str[indexes] <= 'z' ? str[indexes] - ('a' - 'A') : str[indexes])...); } template<class T, std::size_t size> constexpr auto toupper(const T (&str)[size]) -> decltype( toupper_impl(str, typename sprout::index_range<0, size>::type()) ) { return toupper_impl(str, typename sprout::index_range<0, size>::type()); } template<std::size_t size, sprout::index_t... indexes> constexpr auto toupper_impl(const sprout::string<size> str, sprout::index_tuple<indexes...>) -> decltype( sprout::make_string(static_cast<char>('a' <= str[indexes] && str[indexes] <= 'z' ? str[indexes] - ('a' - 'A') : str[indexes])...) ) { return sprout::make_string(static_cast<char>('a' <= str[indexes] && str[indexes] <= 'z' ? str[indexes] - ('a' - 'A') : str[indexes])...); } template<std::size_t size> constexpr auto toupper(const sprout::string<size> str) -> decltype( toupper_impl(str, typename sprout::index_range<0, size>::type()) ) { return toupper_impl(str, typename sprout::index_range<0, size>::type()); } template<class T, std::size_t size, sprout::index_t... indexes> constexpr auto tolower_impl(const T (&str)[size], sprout::index_tuple<indexes...>) -> decltype( sprout::make_string(static_cast<char>('A' <= str[indexes] && str[indexes] <= 'Z' ? str[indexes] + ('a' - 'A') : str[indexes])...) ) { return sprout::make_string(static_cast<char>('A' <= str[indexes] && str[indexes] <= 'Z' ? str[indexes] + ('a' - 'A') : str[indexes])...); } template<class T, std::size_t size> constexpr auto tolower(const T (&str)[size]) -> decltype( tolower_impl(str, typename sprout::index_range<0, size>::type()) ) { return tolower_impl(str, typename sprout::index_range<0, size>::type()); } template<std::size_t size, sprout::index_t... indexes> constexpr auto tolower_impl(const sprout::string<size> str, sprout::index_tuple<indexes...>) -> decltype( sprout::make_string(static_cast<char>('A' <= str[indexes] && str[indexes] <= 'Z' ? str[indexes] + ('a' - 'A') : str[indexes])...) ) { return sprout::make_string(static_cast<char>('A' <= str[indexes] && str[indexes] <= 'Z' ? str[indexes] + ('a' - 'A') : str[indexes])...); } template<std::size_t size> constexpr auto tolower(const sprout::string<size> str) -> decltype( tolower_impl(str, typename sprout::index_range<0, size>::type()) ) { return tolower_impl(str, typename sprout::index_range<0, size>::type()); } int main() { constexpr auto upp1 = toupper("sprout"); constexpr auto low1 = tolower("SPROUT"); constexpr auto upp2 = toupper(low1); constexpr auto low2 = tolower(upp1); static_assert(upp1 == "SPROUT", ""); static_assert(low1 == "sprout", ""); static_assert(upp2 == "SPROUT", ""); static_assert(low2 == "sprout", ""); }