void testSizes()
{
static_assert("He"_cs.size() == 2, "size() is wrong");
static_assert(L"Wo"_cs.size() == 2, "size() is wrong");
static_assert(u"Hello!"_cs.size() == 6, "size() is wrong");
static_assert(U"World!"_cs.size() == 6, "size() is wrong");
}
void testEmptyStrings()
{
constexpr auto mb = ""_cs;
constexpr auto wide = L""_cs;
constexpr auto utf16 = u""_cs;
constexpr auto utf32 = U""_cs;
static_assert(mb.size() == 0, "Multi-byte size() is wrong");
static_assert(wide.size() == 0, "Wide size() is wrong");
static_assert(utf16.size() == 0, "UTF-16 size() is wrong");
static_assert(utf32.size() == 0, "UTF-32 size() is wrong");
static_assert(mb.length() == 0, "Multi-byte length() is wrong");
static_assert(wide.length() == 0, "Wide length() is wrong");
static_assert(utf16.length() == 0, "UTF-16 length() is wrong");
static_assert(utf32.length() == 0, "UTF-32 length() is wrong");
static_assert(mb.empty() == true, "Multi-byte empty() is wrong");
static_assert(wide.empty() == true, "Wide empty() is wrong");
static_assert(utf16.empty() == true, "UTF-16 empty() is wrong");
static_assert(utf32.empty() == true, "UTF-32 empty() is wrong");
static_assert(mb == ""_cs, "operator==() is wrong");
static_assert(mb != " "_cs, "operator!=() is wrong");
}
void testSearching()
{
constexpr auto hi = "Hello "_cs + "World!"_cs;
static_assert(hi.find('?') == std::string::npos, "find() is wrong");
static_assert(hi.find(' ') == 5, "find() is wrong");
static_assert(hi.find('o') == 4, "find() is wrong");
static_assert(hi.find("orl"_cs) == 7, "find() is wrong");
static_assert(hi.rfind('o') == 7, "rfind() is wrong");
static_assert(hi.rfind("el"_cs) == 1, "rfind() is wrong");
}
void testSubstringFunctions()
{
constexpr auto big = "Hello, World!"_cs;
constexpr auto smaller = big.substr<7>();
constexpr auto lessbig = big.cdr();
static_assert(smaller.size() == 6, "substr<>() is wrong");
static_assert(smaller[0UL] == 'W', "substr<>() is wrong");
static_assert(big.substr<0>().at(0) == 'H', "substr<>() is wrong");
static_assert(big.substr<12>().at(0) == '!', "substr<>() is wrong");
static_assert(big.size() == lessbig.size() + 1, "cdr() is wrong");
}
void testComparisons()
{
constexpr auto first = "One"_cs;
constexpr auto second = "Two"_cs;
constexpr auto last = "One"_cs;
static_assert(first.compare(last) == 0, "compare() is wrong");
static_assert(first.compare(second) == -1, "compare() is wrong");
static_assert(second.compare(last) == 1, "compare() is wrong");
static_assert("A"_cs == "A"_cs, "operator== is wrong");
static_assert("A"_cs != "a"_cs, "operator!= is wrong");
static_assert("a"_cs > "A"_cs, "operator> is wrong");
static_assert("1"_cs < "2"_cs, "operator< is wrong");
}
void testConversions()
{
static_assert("0"_cs.to_number() == 0, "to_number() is wrong");
static_assert("1"_cs.to_number() == 1, "to_number() is wrong");
static_assert("11"_cs.to_number() == 11, "to_number() is wrong");
static_assert("65535"_cs.to_number() == 65535, "to_number() is wrong");
//"99kj343"_cs.to_number();
constexpr ptrdiff_t number = "12345"_cs;
static_assert(number == 12345, "operator size_type is wrong");
//constexpr ptrdiff_t positive = "+1"_cs;
//static_assert(positive == 1, "to_number() is wrong");
}
void testConcatenation()
{
constexpr auto hello = "Hello"_cs;
constexpr auto world = "World"_cs;
constexpr auto together = hello + ", "_cs + world + "!"_cs;
static_assert(together.size() == 13, "operator+ is wrong");
static_assert(together[5UL] == ',', "operator+ is wrong");
}
template <typename Str>
struct star_wars_speaker
{
star_wars_speaker() { std::cout << "Someone in Star Wars" << std::endl; }
};
template <>
struct star_wars_speaker<decltype("I'd just as soon kiss a Wookiee"_cs)>
{
star_wars_speaker() { std::cout << "Carrie Fisher" << std::endl; }
};
template <>
struct star_wars_speaker<decltype("Luke, I am your father"_cs)>
{
star_wars_speaker() { std::cout << "James Earl Jones" << std::endl; }
};
template <>
struct star_wars_speaker<decltype("Midi-chlorians"_cs)>
{
star_wars_speaker() { std::cout << "Liam Neeson" << std::endl; }
};
void testClassTemplates()
{
auto one = star_wars_speaker<decltype("I'd just as soon kiss a Wookiee"_cs)>();
auto two = star_wars_speaker<decltype("Luke, I am your father"_cs)>();
auto thr = star_wars_speaker<decltype("Midi-chlorian"_cs)>();
auto fur = star_wars_speaker<decltype("How wude!"_cs)>();
}
template <typename Str>
void star_trek_speak(const Str &)
{
std::cout << "Someone in Star Trek" << std::endl;
}
template <>
void star_trek_speak(const decltype("Illogical captain"_cs) &)
{
std::cout << "Leonard Nimoy" << std::endl;
}
template <>
void star_trek_speak(const decltype("He's dead Jim"_cs) &)
{
std::cout << "DeForest Kelley" << std::endl;
}
template <>
void star_trek_speak(const decltype("Oh my"_cs) &)
{
std::cout << "George Takei" << std::endl;
}
void testFunctionTemplates()
{
star_trek_speak("Illogical captain"_cs);
star_trek_speak("He's dead Jim"_cs);
star_trek_speak("Oh my"_cs);
star_trek_speak("Khaaaaaaaaaaannnnnn!"_cs);
}
int main()
{
testSizes();
testEmptyStrings();
testSubstringFunctions();
testComparisons();
testConversions();
testConcatenation();
testClassTemplates();
testFunctionTemplates();
return 0;
}
3. need use cases.
On Sun, Dec 15, 2013 at 10:26 PM, Michael Price - Dev
<michael.b...@gmail.com> wrote:
> I'm considering writing up a proposal to standardize a library type that
> represents a compile-time sequence of character literals. I'm looking for a
> first round of feedback. You can view my prototype implementation at
> https://github.com/michaelbprice/cxx_snippets/blob/master/string_literal/string_literal.cpp
>
> I'm using the top-of-trunk clang to compile with the following command-line:
I think you know that the language feature you used
http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2013/n3599.html
is not a part of C++14.
Anyway.
What's the different between `make_array("str")` and "str"_cs?
http://isocpp.org/files/papers/N3824.html
1. string_literalS are different in types (works with template);
2. string_literal cannot be modified;
3. string_literal has some algorithms as member functions.
So what is the problem you want to solve? Compile-time parsing?
If so, Bristol EWG says:
1. don't think template instantiations is the only way to do it;
2. doubt user to overuse it (a compile time SQL parser is fun,
but what you gain?);
3. need use cases.
constexpr auto library_name = "BEST"_cs;
constexpr auto static_prefix = library_name + ": "_cs;
static_assert(false, static_prefix + "Oops, did I say false"); // would print: "BEST: Oops, did I say false"