Skip to content

Commit

Permalink
#40 Add cstring addition operators
Browse files Browse the repository at this point in the history
  • Loading branch information
rick-de-water committed Jan 8, 2020
1 parent a933953 commit e6fcc4c
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 3 deletions.
46 changes: 43 additions & 3 deletions src/lib/lingo/string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,14 @@ namespace lingo
// Return this
return *this;
}

template <typename _ = int, typename std::enable_if<
std::is_same<encoding::cstring_default_encoding_t<unit_type>, encoding_type>::value &&
std::is_same<page::cstring_default_page_t<unit_type>, page_type>::value, _>::type = 0>
basic_string& operator += (const unit_type* other)
{
return (*this) += string_view(other);
}

basic_string& operator = (const basic_string& string)
{
Expand Down Expand Up @@ -522,7 +530,7 @@ namespace lingo
}

template <typename Encoding, typename Page, typename ResultAllocator = internal::default_allocator<Encoding>>
basic_string<Encoding, Page, ResultAllocator> operator + (basic_string_view<Encoding, Page> left, basic_string_view<Encoding, Page> right)
basic_string<Encoding, Page, ResultAllocator> operator + (const basic_string_view<Encoding, Page>& left, const basic_string_view<Encoding, Page>& right)
{
basic_string<Encoding, Page, ResultAllocator> result;
result.reserve(left.size() + right.size());
Expand All @@ -532,7 +540,7 @@ namespace lingo
}

template <typename Encoding, typename Page, typename LeftAllocator, typename ResultAllocator = LeftAllocator>
basic_string<Encoding, Page, ResultAllocator> operator + (basic_string<Encoding, Page, LeftAllocator> left, typename Encoding::point_type right)
basic_string<Encoding, Page, ResultAllocator> operator + (const basic_string<Encoding, Page, LeftAllocator>& left, typename Encoding::point_type right)
{
basic_string<Encoding, Page, ResultAllocator> result;
result.reserve(left.size() + Encoding::max_units);
Expand All @@ -542,7 +550,7 @@ namespace lingo
}

template <typename Encoding, typename Page, typename RightAllocator, typename ResultAllocator = RightAllocator>
basic_string<Encoding, Page, ResultAllocator> operator + (typename Encoding::point_type left, basic_string<Encoding, Page, RightAllocator> right)
basic_string<Encoding, Page, ResultAllocator> operator + (typename Encoding::point_type left, const basic_string<Encoding, Page, RightAllocator>& right)
{
basic_string<Encoding, Page, ResultAllocator> result;
result.reserve(right.size() + Encoding::max_units);
Expand All @@ -551,6 +559,38 @@ namespace lingo
return result;
}

template <typename Encoding, typename Page, typename LeftAllocator, typename ResultAllocator = LeftAllocator, typename std::enable_if<
std::is_same<encoding::cstring_default_encoding_t<typename Encoding::unit_type>, Encoding>::value &&
std::is_same<page::cstring_default_page_t<typename Encoding::unit_type>, Page>::value, int>::type = 0>
basic_string<Encoding, Page, ResultAllocator> operator + (const basic_string<Encoding, Page, LeftAllocator>& left, const typename Encoding::unit_type* right)
{
return left + basic_string_view<Encoding, Page>(right);
}

template <typename Encoding, typename Page, typename RightAllocator, typename ResultAllocator = RightAllocator, typename std::enable_if<
std::is_same<encoding::cstring_default_encoding_t<typename Encoding::unit_type>, Encoding>::value &&
std::is_same<page::cstring_default_page_t<typename Encoding::unit_type>, Page>::value, int>::type = 0>
basic_string<Encoding, Page, ResultAllocator> operator + (const typename Encoding::unit_type* left, const basic_string<Encoding, Page, RightAllocator>& right)
{
return basic_string_view<Encoding, Page>(left) + right;
}

template <typename Encoding, typename Page, typename std::enable_if<
std::is_same<encoding::cstring_default_encoding_t<typename Encoding::unit_type>, Encoding>::value &&
std::is_same<page::cstring_default_page_t<typename Encoding::unit_type>, Page>::value, int>::type = 0>
basic_string<Encoding, Page> operator + (basic_string_view<Encoding, Page> left, const typename Encoding::unit_type* right)
{
return left + basic_string_view<Encoding, Page>(right);
}

template <typename Encoding, typename Page, typename std::enable_if<
std::is_same<encoding::cstring_default_encoding_t<typename Encoding::unit_type>, Encoding>::value &&
std::is_same<page::cstring_default_page_t<typename Encoding::unit_type>, Page>::value, int>::type = 0>
basic_string<Encoding, Page> operator + (const typename Encoding::unit_type* left, basic_string_view<Encoding, Page> right)
{
return basic_string_view<Encoding, Page>(left) + right;
}

template <typename Encoding, typename Page, typename LeftAllocator, typename RightAllocator>
bool operator == (const basic_string<Encoding, Page, LeftAllocator>& left, const basic_string<Encoding, Page, RightAllocator>& right) noexcept(noexcept(left.compare(right)))
{
Expand Down
49 changes: 49 additions & 0 deletions tests/lingo/string.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -618,4 +618,53 @@ LINGO_UNIT_TEST_CASE("A character can be concatenated to a string")
++suffix_assign_iterator;
}
}
}

LINGO_UNIT_TEST_CASE("A cstring can be concatenated to a string")
{
LINGO_UNIT_TEST_TYPEDEFS;

const string_view_type source_string = lingo::test::test_string<unit_type>::value;
string_type prefix_test_string = source_string;
string_type suffix_test_string = source_string;

REQUIRE(source_string.null_terminated());
prefix_test_string = source_string.data() + prefix_test_string;
suffix_test_string = suffix_test_string + source_string.data();

REQUIRE(string_view_type(prefix_test_string.data(), source_string.size()) == source_string);
REQUIRE(string_view_type(prefix_test_string.data() + source_string.size(), source_string.size()) == source_string);

REQUIRE(string_view_type(suffix_test_string.data(), source_string.size()) == source_string);
REQUIRE(string_view_type(suffix_test_string.data() + source_string.size(), source_string.size()) == source_string);

for (size_type i = 0; i < 10; ++i)
{
prefix_test_string += source_string.data();
REQUIRE(prefix_test_string.size() == source_string.size() * (i + 3));

for (size_type j = 0; j < i + 3; ++j)
{
REQUIRE(string_view_type(prefix_test_string.data() + source_string.size() * j, source_string.size()) == source_string);
}
}
}

LINGO_UNIT_TEST_CASE("A cstring can be concatenated to a string_view")
{
LINGO_UNIT_TEST_TYPEDEFS;

const string_view_type source_string = lingo::test::test_string<unit_type>::value;
const string_view_type prefix_test_string = source_string;
const string_view_type suffix_test_string = source_string;

REQUIRE(source_string.null_terminated());
const string_type prefix_test_string_result = source_string.data() + prefix_test_string;
const string_type suffix_test_string_result = suffix_test_string + source_string.data();

REQUIRE(string_view_type(prefix_test_string_result.data(), source_string.size()) == source_string);
REQUIRE(string_view_type(prefix_test_string_result.data() + source_string.size(), source_string.size()) == source_string);

REQUIRE(string_view_type(suffix_test_string_result.data(), source_string.size()) == source_string);
REQUIRE(string_view_type(suffix_test_string_result.data() + source_string.size(), source_string.size()) == source_string);
}

0 comments on commit e6fcc4c

Please sign in to comment.