diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
commit | 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch) | |
tree | e5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/container/test/string_test.cpp | |
parent | Initial commit. (diff) | |
download | ceph-upstream.tar.xz ceph-upstream.zip |
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/container/test/string_test.cpp')
-rw-r--r-- | src/boost/libs/container/test/string_test.cpp | 596 |
1 files changed, 596 insertions, 0 deletions
diff --git a/src/boost/libs/container/test/string_test.cpp b/src/boost/libs/container/test/string_test.cpp new file mode 100644 index 00000000..b2d17f6a --- /dev/null +++ b/src/boost/libs/container/test/string_test.cpp @@ -0,0 +1,596 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2004-2013. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#include <boost/container/detail/config_begin.hpp> +#include <boost/container/vector.hpp> +#include <boost/container/string.hpp> +#include <string> +#include <vector> +#include <boost/container/detail/algorithm.hpp> //equal() +#include <cstring> +#include <cstdio> +#include <cstddef> +#include <new> +#include "dummy_test_allocator.hpp" +#include "check_equal_containers.hpp" +#include "expand_bwd_test_allocator.hpp" +#include "expand_bwd_test_template.hpp" +#include "propagate_allocator_test.hpp" +#include "default_init_test.hpp" +#include "comparison_test.hpp" +#include "../../intrusive/test/iterator_test.hpp" +#include <boost/utility/string_view.hpp> +#include <boost/core/lightweight_test.hpp> + +using namespace boost::container; + +struct StringEqual +{ + template<class Str1, class Str2> + bool operator ()(const Str1 &string1, const Str2 &string2) const + { + if(string1.size() != string2.size()) + return false; + return std::char_traits<typename Str1::value_type>::compare + (string1.c_str(), string2.c_str(), string1.size()) == 0; + } +}; + +//Function to check if both lists are equal +template<class StrVector1, class StrVector2> +bool CheckEqualStringVector(StrVector1 *strvect1, StrVector2 *strvect2) +{ + StringEqual comp; + return boost::container::algo_equal(strvect1->begin(), strvect1->end(), + strvect2->begin(), comp); +} + +template<class ForwardIt> +ForwardIt unique(ForwardIt first, ForwardIt const last) +{ + if(first == last){ + ForwardIt i = first; + //Find first adjacent pair + while(1){ + if(++i == last){ + return last; + } + else if(*first == *i){ + break; + } + ++first; + } + //Now overwrite skipping adjacent elements + while (++i != last) { + if (!(*first == *i)) { + *(++first) = boost::move(*i); + } + } + ++first; + } + return first; +} + +template<class CharType> +struct string_literals; + +template<> +struct string_literals<char> +{ + static const char *String() + { return "String"; } + static const char *Prefix() + { return "Prefix"; } + static const char *Suffix() + { return "Suffix"; } + static const char *LongString() + { return "LongLongLongLongLongLongLongLongLongLongLongLongLongString"; } + static char Char() + { return 'C'; } + static void sprintf_number(char *buf, int number) + { + std::sprintf(buf, "%i", number); + } +}; + +template<> +struct string_literals<wchar_t> +{ + static const wchar_t *String() + { return L"String"; } + static const wchar_t *Prefix() + { return L"Prefix"; } + static const wchar_t *Suffix() + { return L"Suffix"; } + static const wchar_t *LongString() + { return L"LongLongLongLongLongLongLongLongLongLongLongLongLongString"; } + static wchar_t Char() + { return L'C'; } + static void sprintf_number(wchar_t *buffer, unsigned int number) + { + //For compilers without wsprintf, print it backwards + const wchar_t *digits = L"0123456789"; + wchar_t *buf = buffer; + + while(1){ + int rem = number % 10; + number = number / 10; + + *buf = digits[rem]; + ++buf; + if(!number){ + *buf = 0; + break; + } + } + + } +}; + +template<class CharType> +int string_test() +{ + typedef std::basic_string<CharType> StdString; + typedef vector<StdString> StdStringVector; + typedef basic_string<CharType> BoostString; + typedef vector<BoostString> BoostStringVector; + + const int MaxSize = 100; + + { + BoostStringVector *boostStringVect = new BoostStringVector; + StdStringVector *stdStringVect = new StdStringVector; + BoostString auxBoostString; + StdString auxStdString(StdString(auxBoostString.begin(), auxBoostString.end() )); + + CharType buffer [20]; + + //First, push back + for(int i = 0; i < MaxSize; ++i){ + auxBoostString = string_literals<CharType>::String(); + auxStdString = string_literals<CharType>::String(); + string_literals<CharType>::sprintf_number(buffer, i); + auxBoostString += buffer; + auxStdString += buffer; + boostStringVect->push_back(auxBoostString); + stdStringVect->push_back(auxStdString); + } + + if(auxBoostString.data() != const_cast<const BoostString&>(auxBoostString).data() && + auxBoostString.data() != &auxBoostString[0]) + return 1; + + if(!CheckEqualStringVector(boostStringVect, stdStringVect)){ + return 1; + } + + //Now push back moving + for(int i = 0; i < MaxSize; ++i){ + auxBoostString = string_literals<CharType>::String(); + auxStdString = string_literals<CharType>::String(); + string_literals<CharType>::sprintf_number(buffer, i); + auxBoostString += buffer; + auxStdString += buffer; + boostStringVect->push_back(boost::move(auxBoostString)); + stdStringVect->push_back(auxStdString); + } + + if(!CheckEqualStringVector(boostStringVect, stdStringVect)){ + return 1; + } + + //push front + for(int i = 0; i < MaxSize; ++i){ + auxBoostString = string_literals<CharType>::String(); + auxStdString = string_literals<CharType>::String(); + string_literals<CharType>::sprintf_number(buffer, i); + auxBoostString += buffer; + auxStdString += buffer; + boostStringVect->insert(boostStringVect->begin(), auxBoostString); + stdStringVect->insert(stdStringVect->begin(), auxStdString); + } + + if(!CheckEqualStringVector(boostStringVect, stdStringVect)){ + return 1; + } + + //Now push front moving + for(int i = 0; i < MaxSize; ++i){ + auxBoostString = string_literals<CharType>::String(); + auxStdString = string_literals<CharType>::String(); + string_literals<CharType>::sprintf_number(buffer, i); + auxBoostString += buffer; + auxStdString += buffer; + boostStringVect->insert(boostStringVect->begin(), boost::move(auxBoostString)); + stdStringVect->insert(stdStringVect->begin(), auxStdString); + } + + if(!CheckEqualStringVector(boostStringVect, stdStringVect)){ + return 1; + } + + //Now test long and short representation swapping + + //Short first + auxBoostString = string_literals<CharType>::String(); + auxStdString = string_literals<CharType>::String(); + BoostString boost_swapper; + StdString std_swapper; + boost_swapper.swap(auxBoostString); + std_swapper.swap(auxStdString); + if(!StringEqual()(auxBoostString, auxStdString)) + return 1; + if(!StringEqual()(boost_swapper, std_swapper)) + return 1; + boost_swapper.swap(auxBoostString); + std_swapper.swap(auxStdString); + if(!StringEqual()(auxBoostString, auxStdString)) + return 1; + if(!StringEqual()(boost_swapper, std_swapper)) + return 1; + + //Shrink_to_fit + auxBoostString.shrink_to_fit(); + StdString(auxStdString).swap(auxStdString); + if(!StringEqual()(auxBoostString, auxStdString)) + return 1; + + //Reserve + shrink_to_fit + auxBoostString.reserve(boost_swapper.size()*2+1); + auxStdString.reserve(std_swapper.size()*2+1); + if(!StringEqual()(auxBoostString, auxStdString)) + return 1; + + auxBoostString.shrink_to_fit(); + StdString(auxStdString).swap(auxStdString); + if(!StringEqual()(auxBoostString, auxStdString)) + return 1; + + //Long string + auxBoostString = string_literals<CharType>::LongString(); + auxStdString = string_literals<CharType>::LongString(); + boost_swapper = BoostString(); + std_swapper = StdString(); + boost_swapper.swap(auxBoostString); + std_swapper.swap(auxStdString); + if(!StringEqual()(auxBoostString, auxStdString)) + return 1; + if(!StringEqual()(boost_swapper, std_swapper)) + return 1; + boost_swapper.swap(auxBoostString); + std_swapper.swap(auxStdString); + + //Shrink_to_fit + auxBoostString.shrink_to_fit(); + StdString(auxStdString).swap(auxStdString); + if(!StringEqual()(auxBoostString, auxStdString)) + return 1; + + auxBoostString.clear(); + auxStdString.clear(); + auxBoostString.shrink_to_fit(); + StdString(auxStdString).swap(auxStdString); + if(!StringEqual()(auxBoostString, auxStdString)) + return 1; + + //No sort + std::sort(boostStringVect->begin(), boostStringVect->end()); + std::sort(stdStringVect->begin(), stdStringVect->end()); + if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1; + + const CharType *prefix = string_literals<CharType>::Prefix(); + const int prefix_size = std::char_traits<CharType>::length(prefix); + const CharType *sufix = string_literals<CharType>::Suffix(); + + for(int i = 0; i < MaxSize; ++i){ + (*boostStringVect)[i].append(sufix); + (*stdStringVect)[i].append(sufix); + (*boostStringVect)[i].insert((*boostStringVect)[i].begin(), + prefix, prefix + prefix_size); + (*stdStringVect)[i].insert((*stdStringVect)[i].begin(), + prefix, prefix + prefix_size); + } + + if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1; + + for(int i = 0; i < MaxSize; ++i){ + std::reverse((*boostStringVect)[i].begin(), (*boostStringVect)[i].end()); + std::reverse((*stdStringVect)[i].begin(), (*stdStringVect)[i].end()); + } + + if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1; + + for(int i = 0; i < MaxSize; ++i){ + std::reverse((*boostStringVect)[i].begin(), (*boostStringVect)[i].end()); + std::reverse((*stdStringVect)[i].begin(), (*stdStringVect)[i].end()); + } + + if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1; + + for(int i = 0; i < MaxSize; ++i){ + std::sort(boostStringVect->begin(), boostStringVect->end()); + std::sort(stdStringVect->begin(), stdStringVect->end()); + } + + if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1; + + for(int i = 0; i < MaxSize; ++i){ + (*boostStringVect)[i].replace((*boostStringVect)[i].begin(), + (*boostStringVect)[i].end(), + string_literals<CharType>::String()); + (*stdStringVect)[i].replace((*stdStringVect)[i].begin(), + (*stdStringVect)[i].end(), + string_literals<CharType>::String()); + } + + if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1; + + boostStringVect->erase(::unique(boostStringVect->begin(), boostStringVect->end()), + boostStringVect->end()); + stdStringVect->erase(::unique(stdStringVect->begin(), stdStringVect->end()), + stdStringVect->end()); + if(!CheckEqualStringVector(boostStringVect, stdStringVect)) return 1; + + //Check addition + { + BoostString bs2 = string_literals<CharType>::String(); + StdString ss2 = string_literals<CharType>::String(); + BoostString bs3 = string_literals<CharType>::Suffix(); + StdString ss3 = string_literals<CharType>::Suffix(); + BoostString bs4 = bs2 + bs3; + StdString ss4 = ss2 + ss3; + if(!StringEqual()(bs4, ss4)){ + return 1; + } + + bs4 = bs2 + BoostString(); + ss4 = ss2 + StdString(); + if(!StringEqual()(bs4, ss4)){ + return 1; + } + + bs4 = BoostString() + bs2; + ss4 = StdString() + ss2; + if(!StringEqual()(bs4, ss4)){ + return 1; + } + + bs4 = BoostString() + boost::move(bs2); + ss4 = StdString() + boost::move(ss2); + if(!StringEqual()(bs4, ss4)){ + return 1; + } + + bs2 = string_literals<CharType>::String(); + ss2 = string_literals<CharType>::String(); + bs4 = boost::move(bs2) + BoostString(); + ss4 = boost::move(ss2) + StdString(); + if(!StringEqual()(bs4, ss4)){ + return 1; + } + + bs2 = string_literals<CharType>::String(); + ss2 = string_literals<CharType>::String(); + bs4 = string_literals<CharType>::Prefix() + boost::move(bs2); + ss4 = string_literals<CharType>::Prefix() + boost::move(ss2); + if(!StringEqual()(bs4, ss4)){ + return 1; + } + + bs2 = string_literals<CharType>::String(); + ss2 = string_literals<CharType>::String(); + bs4 = boost::move(bs2) + string_literals<CharType>::Suffix(); + ss4 = boost::move(ss2) + string_literals<CharType>::Suffix(); + if(!StringEqual()(bs4, ss4)){ + return 1; + } + + bs2 = string_literals<CharType>::String(); + ss2 = string_literals<CharType>::String(); + bs4 = string_literals<CharType>::Prefix() + bs2; + ss4 = string_literals<CharType>::Prefix() + ss2; + if(!StringEqual()(bs4, ss4)){ + return 1; + } + + bs2 = string_literals<CharType>::String(); + ss2 = string_literals<CharType>::String(); + bs4 = bs2 + string_literals<CharType>::Suffix(); + ss4 = ss2 + string_literals<CharType>::Suffix(); + if(!StringEqual()(bs4, ss4)){ + return 1; + } + + bs2 = string_literals<CharType>::String(); + ss2 = string_literals<CharType>::String(); + bs4 = string_literals<CharType>::Char() + bs2; + ss4 = string_literals<CharType>::Char() + ss2; + if(!StringEqual()(bs4, ss4)){ + return 1; + } + + bs2 = string_literals<CharType>::String(); + ss2 = string_literals<CharType>::String(); + bs4 = bs2 + string_literals<CharType>::Char(); + ss4 = ss2 + string_literals<CharType>::Char(); + if(!StringEqual()(bs4, ss4)){ + return 1; + } + + //Check front/back/begin/end + + if(bs4.front() != *ss4.begin()) + return 1; + + if(bs4.back() != *(ss4.end()-1)) + return 1; + + bs4.pop_back(); + ss4.erase(ss4.end()-1); + if(!StringEqual()(bs4, ss4)){ + return 1; + } + + if(*bs4.begin() != *ss4.begin()) + return 1; + if(*bs4.cbegin() != *ss4.begin()) + return 1; + if(*bs4.rbegin() != *ss4.rbegin()) + return 1; + if(*bs4.crbegin() != *ss4.rbegin()) + return 1; + if(*(bs4.end()-1) != *(ss4.end()-1)) + return 1; + if(*(bs4.cend()-1) != *(ss4.end()-1)) + return 1; + if(*(bs4.rend()-1) != *(ss4.rend()-1)) + return 1; + if(*(bs4.crend()-1) != *(ss4.rend()-1)) + return 1; + } + +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD + //Chect Constructor Template Auto Deduction + { + auto gold = StdString(string_literals<CharType>::String()); + auto test = basic_string(gold.begin(), gold.end()); + if(!StringEqual()(gold, test)) { + return 1; + } + } +#endif + + + //When done, delete vector + delete boostStringVect; + delete stdStringVect; + } + return 0; +} + +bool test_expand_bwd() +{ + //Now test all back insertion possibilities + typedef test::expand_bwd_test_allocator<char> + allocator_type; + typedef basic_string<char, std::char_traits<char>, allocator_type> + string_type; + return test::test_all_expand_bwd<string_type>(); +} + +struct boost_container_string; + +namespace boost { namespace container { namespace test { + +template<> +struct alloc_propagate_base<boost_container_string> +{ + template <class T, class Allocator> + struct apply + { + typedef boost::container::basic_string<T, std::char_traits<T>, Allocator> type; + }; +}; + + +}}} //namespace boost::container::test + + +int main() +{ + if(string_test<char>()){ + return 1; + } + + if(string_test<wchar_t>()){ + return 1; + } + + //////////////////////////////////// + // Backwards expansion test + //////////////////////////////////// + if(!test_expand_bwd()) + return 1; + + //////////////////////////////////// + // Allocator propagation testing + //////////////////////////////////// + if(!boost::container::test::test_propagate_allocator<boost_container_string>()) + return 1; + + //////////////////////////////////// + // Default init test + //////////////////////////////////// + if(!test::default_init_test< basic_string<char, std::char_traits<char>, test::default_init_allocator<char> > >()){ + std::cerr << "Default init test failed" << std::endl; + return 1; + } + + if(!test::default_init_test< basic_string<wchar_t, std::char_traits<wchar_t>, test::default_init_allocator<wchar_t> > >()){ + std::cerr << "Default init test failed" << std::endl; + return 1; + } + + //////////////////////////////////// + // Iterator testing + //////////////////////////////////// + { + typedef boost::container::basic_string<char> cont_int; + cont_int a; a.push_back(char(1)); a.push_back(char(2)); a.push_back(char(3)); + boost::intrusive::test::test_iterator_random< cont_int >(a); + } + { + typedef boost::container::basic_string<wchar_t> cont_int; + cont_int a; a.push_back(wchar_t(1)); a.push_back(wchar_t(2)); a.push_back(wchar_t(3)); + boost::intrusive::test::test_iterator_random< cont_int >(a); + } + + //////////////////////////////////// + // Comparison testing + //////////////////////////////////// + { + if(!boost::container::test::test_container_comparisons<string>()) + return 1; + if(!boost::container::test::test_container_comparisons<wstring>()) + return 1; + } + + //////////////////////////////////// + // has_trivial_destructor_after_move testing + //////////////////////////////////// + // default allocator + { + typedef boost::container::basic_string<char> cont; + typedef cont::allocator_type allocator_type; + typedef boost::container::allocator_traits<allocator_type>::pointer pointer; + if (boost::has_trivial_destructor_after_move<cont>::value != + boost::has_trivial_destructor_after_move<allocator_type>::value && + boost::has_trivial_destructor_after_move<pointer>::value) { + std::cerr << "has_trivial_destructor_after_move(default allocator) test failed" << std::endl; + return 1; + } + } + // std::allocator + { + typedef boost::container::basic_string<char, std::char_traits<char>, std::allocator<char> > cont; + typedef cont::allocator_type allocator_type; + typedef boost::container::allocator_traits<allocator_type>::pointer pointer; + if (boost::has_trivial_destructor_after_move<cont>::value != + boost::has_trivial_destructor_after_move<allocator_type>::value && + boost::has_trivial_destructor_after_move<pointer>::value) { + std::cerr << "has_trivial_destructor_after_move(std::allocator) test failed" << std::endl; + return 1; + } + } + + return boost::report_errors(); +} + +#include <boost/container/detail/config_end.hpp> |