Changed string_view interoperability to a templated solution in order to support also std::string_view.

Added missing members and testcases.
This commit is contained in:
Ion Gaztañaga
2017-02-21 14:27:18 +01:00
parent fde7e1fbdd
commit 865c69bab7
8 changed files with 707 additions and 139 deletions

View File

@ -1217,15 +1217,16 @@ use [*Boost.Container]? There are several reasons for that:
[section:release_notes_boost_1_64_00 Boost 1.64 Release]
* Fixed bugs:
* [@https://svn.boost.org/trac/boost/ticket/12749 Trac #12749 : ['"container::pmr::polymorphic_allocator compilation error"]].
* [@https://svn.boost.org/trac/boost/ticket/12749 Trac #12749: ['"container::pmr::polymorphic_allocator compilation error"]].
* [@https://svn.boost.org/trac/boost/ticket/11333 Trac #11333: ['"boost::basic_string_ref should interop with boost::container::basic_string"]].
[endsect]
[section:release_notes_boost_1_63_00 Boost 1.63 Release]
* Fixed bugs:
* [@https://svn.boost.org/trac/boost/ticket/12534 Trac #12534: ['"flat_map fails to compile if included after type_traits is instantiated under gcc"]].
* [@https://svn.boost.org/trac/boost/ticket/12577 Trac #12577: ['"Null reference in pair.hpp triggers runtime warning with -fsanitize=undefined"]].
* [@https://svn.boost.org/trac/boost/ticket/12534 Trac #12534: ['"flat_map fails to compile if included after type_traits is instantiated under gcc"]].
* [@https://svn.boost.org/trac/boost/ticket/12577 Trac #12577: ['"Null reference in pair.hpp triggers runtime warning with -fsanitize=undefined"]].
* [@https://github.com/boostorg/container/pull/41 GitHub #40: ['Fix parameter types in copy_move_algo.hpp: iterator_traits::difference_type -> allocator_traits::size_type]].
* [@https://github.com/boostorg/container/pull/41 GitHub #41: ['Avoid -Wunreachable-code in do_allocate()]].

View File

@ -49,6 +49,10 @@
#define BOOST_CONTAINER_FALLTHOUGH BOOST_FALLTHOUGH;
#endif
#if defined(BOOST_MSVC) && (_MSC_VER < 1400)
#define BOOST_CONTAINER_TEMPLATED_CONVERSION_OPERATOR_BROKEN
#endif
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) || (defined(BOOST_MSVC) && (BOOST_MSVC == 1700 || BOOST_MSVC == 1600))
#define BOOST_CONTAINER_PAIR_TEST_HAS_HEADER_TUPLE
#endif

View File

@ -58,7 +58,6 @@
#include <climits>
#include <boost/container/detail/type_traits.hpp>
#include <boost/move/traits.hpp>
#include <boost/utility/string_view.hpp>
namespace boost {
namespace container {
@ -616,6 +615,17 @@ class basic_string
this->assign(s.begin(), s.end());
}
//! <b>Effects</b>: Same as basic_string(sv.data(), sv.size(), a).
//!
//! <b>Throws</b>: If allocator_type's default constructor or allocation throws.
template<template <class, class> class BasicStringView>
explicit basic_string(BasicStringView<CharT, Traits> sv, const Allocator& a = Allocator())
: base_t(allocator_traits_type::select_on_container_copy_construction(a))
{
this->priv_terminate_string();
this->assign(sv);
}
//! <b>Effects</b>: Move constructor. Moves s's resources to *this.
//!
//! <b>Throws</b>: Nothing.
@ -853,13 +863,21 @@ class basic_string
}
//! <b>Effects</b>: Assignment from a null-terminated c-string.
//!
basic_string& operator=(const CharT* s)
{ return this->assign(s, s + Traits::length(s)); }
//! <b>Effects</b>: Assignment from character.
//! <b>Effects</b>: Returns: *this = basic_string(1, c).
//!
basic_string& operator=(CharT c)
{ return this->assign(static_cast<size_type>(1), c); }
//! <b>Effects</b>: Equivalent to return assign(sv).
//!
template<template <class, class> class BasicStringView>
basic_string& operator=(BasicStringView<CharT, Traits> sv)
{ return this->assign(sv.data(), sv.size()); }
//! <b>Effects</b>: Returns a copy of the internal allocator.
//!
//! <b>Throws</b>: If allocator's copy constructor throws.
@ -1257,6 +1275,14 @@ class basic_string
basic_string& operator+=(const basic_string& s)
{ return this->append(s); }
//! <b>Effects</b>: Same as `return append(sv)`.
//!
template<template<class, class> class BasicStringView>
basic_string& operator+=(BasicStringView<CharT, Traits> sv)
{
return this->append(sv);
}
//! <b>Effects</b>: Calls append(s).
//!
//! <b>Returns</b>: *this
@ -1275,6 +1301,12 @@ class basic_string
basic_string& append(const basic_string& s)
{ return this->append(s.begin(), s.end()); }
//! <b>Effects</b>: Same as return append(sv.data(), sv.size()).
//!
template<template<class, class> class BasicStringView>
basic_string& append(BasicStringView<CharT, Traits> sv)
{ return this->append(sv.data(), sv.size()); }
//! <b>Requires</b>: pos <= str.size()
//!
//! <b>Effects</b>: Determines the effective length rlen of the string to append
@ -1328,6 +1360,7 @@ class basic_string
{ this->insert(this->end(), first, last); return *this; }
//! <b>Effects</b>: Equivalent to append(static_cast<size_type>(1), c).
//!
void push_back(CharT c)
{
const size_type old_size = this->priv_size();
@ -1349,6 +1382,13 @@ class basic_string
basic_string& assign(const basic_string& s)
{ return this->operator=(s); }
//! <b>Effects</b>: Equivalent to return assign(sv.data(), sv.size()).
//!
//! <b>Returns</b>: *this
template<template <class, class> class BasicStringView>
basic_string& assign(BasicStringView<CharT, Traits> sv)
{ return this->operator=(sv); }
//! <b>Effects</b>: The function replaces the string controlled by *this
//! with a string of length str.size() whose elements are a copy of the string
//! controlled by str. Leaves str in a valid but unspecified state.
@ -1538,6 +1578,12 @@ class basic_string
return *this;
}
//! <b>Effects</b>: Same as `return insert(pos, sv.data(), sv.size())`.
//!
template<template<class, class> class BasicStringView>
basic_string& insert(size_type pos, BasicStringView<CharT, Traits> sv)
{ return this->insert(pos, sv.data(), sv.size()); }
//! <b>Requires</b>: p is a valid iterator on *this.
//!
//! <b>Effects</b>: inserts a copy of c before the character referred to by p.
@ -1550,7 +1596,6 @@ class basic_string
return this->priv_addr() + new_offset;
}
//! <b>Requires</b>: p is a valid iterator on *this.
//!
//! <b>Effects</b>: Inserts n copies of c before the character referred to by p.
@ -1802,6 +1847,14 @@ class basic_string
, str.begin(), str.end());
}
//! <b>Effects</b>: Calls `return replace(pos1, n1, sv.data(), sv.size());`.
//!
template<template<class, class> class BasicStringView>
basic_string& replace(size_type pos1, size_type n1, BasicStringView<CharT, Traits> sv)
{
return this->replace(pos1, n1, sv.data(), sv.size());
}
//! <b>Requires</b>: pos1 <= size() and pos2 <= str.size().
//!
//! <b>Effects</b>: Determines the effective length rlen of the string to be
@ -1812,18 +1865,26 @@ class basic_string
//!
//! <b>Returns</b>: *this
basic_string& replace(size_type pos1, size_type n1,
const basic_string& str, size_type pos2, size_type n2)
const basic_string& str, size_type pos2, size_type n2 = npos)
{
if (pos1 > this->size() || pos2 > str.size())
if (pos2 > str.size())
throw_out_of_range("basic_string::replace out of range position");
const size_type len1 = container_detail::min_value(n1, this->size() - pos1);
const size_type len2 = container_detail::min_value(n2, str.size() - pos2);
if (this->size() - len1 >= this->max_size() - len2)
throw_length_error("basic_string::replace max_size() exceeded");
const pointer addr = this->priv_addr();
const pointer straddr = str.priv_addr();
return this->replace(addr + pos1, addr + pos1 + len1,
straddr + pos2, straddr + pos2 + len2);
return this->replace(pos1, n1, str.data()+pos2, container_detail::min_value(n2, str.size() - pos2));
}
//! <b>Throws</b>: out_of_range if pos1 > size() or pos2 > sv.size().
//!
//! <b>Effects</b>: Determines the effective length rlen of the string to be inserted as the
//! smaller of n2 and sv.size() - pos2 and calls `replace(pos1, n1, sv.data() + pos2, rlen)`.
//!
//! <b>Returns</b>: *this.
template<template<class, class> class BasicStringView>
basic_string& replace(size_type pos1, size_type n1, BasicStringView<CharT, Traits> sv,
size_type pos2, size_type n2 = npos)
{
if (pos2 > sv.size())
throw_out_of_range("basic_string::replace out of range position");
return this->replace(pos1, n1, sv.data()+pos2, container_detail::min_value(n2, sv.size() - pos2));
}
//! <b>Requires</b>: pos1 <= size() and s points to an array of at least n2 elements of CharT.
@ -1837,7 +1898,7 @@ class basic_string
//! the original string controlled by *this beginning at position pos + xlen.
//!
//! <b>Throws</b>: if memory allocation throws, out_of_range if pos1 > size() or length_error
//! if the length of the resulting string would exceed max_size()
//! if the length of the resulting string would exceed max_size()
//!
//! <b>Returns</b>: *this
basic_string& replace(size_type pos1, size_type n1, const CharT* s, size_type n2)
@ -1845,10 +1906,11 @@ class basic_string
if (pos1 > this->size())
throw_out_of_range("basic_string::replace out of range position");
const size_type len = container_detail::min_value(n1, this->size() - pos1);
if (n2 > this->max_size() || size() - len >= this->max_size() - n2)
const size_type max_size = this->max_size();
if (n2 > max_size || (this->size() - len) >= (max_size - n2))
throw_length_error("basic_string::replace max_size() exceeded");
const pointer addr = this->priv_addr();
return this->replace(addr + pos1, addr + pos1 + len, s, s + n2);
const pointer addr = this->priv_addr() + pos1;
return this->replace(addr, addr + len, s, s + n2);
}
//! <b>Requires</b>: pos1 <= size() and s points to an array of at least n2 elements of CharT.
@ -1867,15 +1929,7 @@ class basic_string
//! <b>Returns</b>: *this
basic_string& replace(size_type pos, size_type n1, const CharT* s)
{
if (pos > this->size())
throw_out_of_range("basic_string::replace out of range position");
const size_type len = container_detail::min_value(n1, this->size() - pos);
const size_type n2 = Traits::length(s);
if (n2 > this->max_size() || this->size() - len >= this->max_size() - n2)
throw_length_error("basic_string::replace max_size() exceeded");
const pointer addr = this->priv_addr();
return this->replace(addr + pos, addr + pos + len,
s, s + Traits::length(s));
return this->replace(pos, n1, s, Traits::length(s));
}
//! <b>Requires</b>: pos1 <= size().
@ -1905,7 +1959,7 @@ class basic_string
//!
//! <b>Returns</b>: *this
basic_string& replace(const_iterator i1, const_iterator i2, const basic_string& str)
{ return this->replace(i1, i2, str.begin(), str.end()); }
{ return this->replace(i1, i2, str.data(), str.data()+str.size()); }
//! <b>Requires</b>: [begin(),i1) and [i1,i2) are valid ranges and
//! s points to an array of at least n elements
@ -2005,6 +2059,18 @@ class basic_string
}
#endif
//! <b>Requires</b>: [begin(), i1) and [i1, i2) are valid ranges.
//!
//! <b>Effects</b>: Calls `replace(i1 - begin(), i2 - i1, sv).`.
//!
//! <bReturns</b>: *this.
template<template <class, class> class BasicStringView>
basic_string& replace(const_iterator i1, const_iterator i2, BasicStringView<CharT, Traits> sv)
{
return this->replace(static_cast<size_type>(i1 - this->cbegin())
,static_cast<size_type>(i2 - i1) ,sv);
}
//! <b>Requires</b>: pos <= size()
//!
//! <b>Effects</b>: Determines the effective length rlen of the string to copy as the
@ -2060,12 +2126,25 @@ class basic_string
const CharT* data() const BOOST_NOEXCEPT_OR_NOTHROW
{ return container_detail::to_raw_pointer(this->priv_addr()); }
#ifndef BOOST_CONTAINER_TEMPLATED_CONVERSION_OPERATOR_BROKEN
//! <b>Returns</b>: a string_view to the characters in the string.
//!
//! <b>Complexity</b>: constant time.
operator boost::basic_string_view<CharT, Traits>() const BOOST_NOEXCEPT_OR_NOTHROW
{ return boost::basic_string_view<CharT, Traits>(data(), size()); }
template<template <class, class> class BasicStringView>
operator BasicStringView<CharT, Traits>() const BOOST_NOEXCEPT_OR_NOTHROW
{ return this->to_view< BasicStringView<CharT, Traits> >(); }
#endif
//! <b>Returns</b>: a string_view to the characters in the string.
//!
//! <b>Complexity</b>: constant time.
//!
//! <b>Note</b>: This function is available to write portable code for compilers
//! that don't support templated conversion operators.
template<class BasicStringView>
BasicStringView to_view() const BOOST_NOEXCEPT_OR_NOTHROW
{ return BasicStringView(this->data(), this->size()); }
//////////////////////////////////////////////
//
// string operations
@ -2073,7 +2152,8 @@ class basic_string
//////////////////////////////////////////////
//! <b>Effects</b>: Determines the lowest position xpos, if possible, such that both
//! of the following conditions obtain: 19 pos <= xpos and xpos + str.size() <= size();
//! of the following conditions hold:
//! 1) pos <= xpos and xpos + str.size() <= size();
//! 2) traits::eq(at(xpos+I), str.at(I)) for all elements I of the string controlled by str.
//!
//! <b>Throws</b>: Nothing
@ -2082,6 +2162,18 @@ class basic_string
size_type find(const basic_string& s, size_type pos = 0) const
{ return find(s.c_str(), pos, s.size()); }
//! <b>Effects</b>: Determines the lowest position xpos, if possible, such that both
//! of the following conditions hold:
//! 1) pos <= xpos and xpos + sv.size() <= size();
//! 2) traits::eq(at(xpos+I), sv.at(I)) for all elements I of the string controlled by sv.
//!
//! <b>Throws</b>: Nothing
//!
//! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
template<template <class, class> class BasicStringView>
size_type find(BasicStringView<CharT, Traits> sv, size_type pos = 0) const
{ return find(sv.data(), pos, sv.size()); }
//! <b>Requires</b>: s points to an array of at least n elements of CharT.
//!
//! <b>Throws</b>: Nothing
@ -2139,6 +2231,18 @@ class basic_string
size_type rfind(const basic_string& str, size_type pos = npos) const
{ return rfind(str.c_str(), pos, str.size()); }
//! <b>Effects</b>: Determines the highest position xpos, if possible, such
//! that both of the following conditions obtain:
//! a) xpos <= pos and xpos + sv.size() <= size();
//! b) traits::eq(at(xpos+I), sv.at(I)) for all elements I of the string controlled by sv.
//!
//! <b>Throws</b>: Nothing
//!
//! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
template<template <class, class> class BasicStringView>
size_type rfind(BasicStringView<CharT, Traits> sv, size_type pos = npos) const
{ return rfind(sv.data(), pos, sv.size()); }
//! <b>Requires</b>: s points to an array of at least n elements of CharT.
//!
//! <b>Throws</b>: Nothing
@ -2195,8 +2299,19 @@ class basic_string
//! <b>Throws</b>: Nothing
//!
//! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
size_type find_first_of(const basic_string& s, size_type pos = 0) const
{ return find_first_of(s.c_str(), pos, s.size()); }
size_type find_first_of(const basic_string& str, size_type pos = 0) const
{ return find_first_of(str.c_str(), pos, str.size()); }
//! <b>Effects</b>: Determines the lowest position xpos, if possible, such that both of the
//! following conditions obtain: a) pos <= xpos and xpos < size();
//! b) traits::eq(at(xpos), sv.at(I)) for some element I of the string controlled by sv.
//!
//! <b>Throws</b>: Nothing
//!
//! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
template<template <class, class> class BasicStringView>
size_type find_first_of(BasicStringView<CharT, Traits> sv, size_type pos = 0) const
{ return find_first_of(sv.data(), pos, sv.size()); }
//! <b>Requires</b>: s points to an array of at least n elements of CharT.
//!
@ -2243,6 +2358,17 @@ class basic_string
size_type find_last_of(const basic_string& str, size_type pos = npos) const
{ return find_last_of(str.c_str(), pos, str.size()); }
//! <b>Effects</b>: Determines the highest position xpos, if possible, such that both of
//! the following conditions obtain: a) xpos <= pos and xpos < size(); b)
//! traits::eq(at(xpos), str.at(I)) for some element I of the string controlled by str.
//!
//! <b>Throws</b>: Nothing
//!
//! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
template<template <class, class> class BasicStringView>
size_type find_last_of(BasicStringView<CharT, Traits> sv, size_type pos = npos) const
{ return find_last_of(sv.data(), pos, sv.size()); }
//! <b>Requires</b>: s points to an array of at least n elements of CharT.
//!
//! <b>Throws</b>: Nothing
@ -2289,6 +2415,18 @@ class basic_string
size_type find_first_not_of(const basic_string& str, size_type pos = 0) const
{ return find_first_not_of(str.c_str(), pos, str.size()); }
//! <b>Effects</b>: Determines the lowest position xpos, if possible, such that
//! both of the following conditions obtain:
//! a) pos <= xpos and xpos < size(); b) traits::eq(at(xpos), sv.at(I)) for no
//! element I of the string controlled by sv.
//!
//! <b>Throws</b>: Nothing
//!
//! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
template<template <class, class> class BasicStringView>
size_type find_first_not_of(BasicStringView<CharT, Traits> sv, size_type pos = 0) const
{ return find_first_not_of(sv.data(), pos, sv.size()); }
//! <b>Requires</b>: s points to an array of at least traits::length(s) + 1 elements of CharT.
//!
//! <b>Throws</b>: Nothing
@ -2342,6 +2480,17 @@ class basic_string
size_type find_last_not_of(const basic_string& str, size_type pos = npos) const
{ return find_last_not_of(str.c_str(), pos, str.size()); }
//! <b>Effects</b>: Determines the highest position xpos, if possible, such that
//! both of the following conditions obtain: a) xpos <= pos and xpos < size();
//! b) traits::eq(at(xpos), sv.at(I)) for no element I of the string controlled by sv.
//!
//! <b>Throws</b>: Nothing
//!
//! <b>Returns</b>: xpos if the function can determine such a value for xpos. Otherwise, returns npos.
template<template <class, class> class BasicStringView>
size_type find_last_not_of(BasicStringView<CharT, Traits> sv, size_type pos = npos) const
{ return find_last_not_of(sv.data(), pos, sv.size()); }
//! <b>Requires</b>: s points to an array of at least n elements of CharT.
//!
//! <b>Throws</b>: Nothing
@ -2405,7 +2554,7 @@ class basic_string
addr + pos + container_detail::min_value(n, size() - pos), this->alloc());
}
//! <b>Effects</b>: Determines the effective length rlen of the string to copy as
//! <b>Effects</b>: Determines the effective length rlen of the string to compare as
//! the smaller of size() and str.size(). The function then compares the two strings by
//! calling traits::compare(data(), str.data(), rlen).
//!
@ -2421,10 +2570,21 @@ class basic_string
return s_compare(addr, addr + this->priv_size(), str_addr, str_addr + str.priv_size());
}
//! <b>Throws</b>: Nothing
//!
//! <b>Returns</b>: compare(basic_string(sv)).
template<template <class, class> class BasicStringView>
int compare(BasicStringView<CharT,Traits> sv) const
{
const pointer addr = this->priv_addr();
return s_compare(addr, addr + this->priv_size(), sv.data(), sv.data() + sv.size());
}
//! <b>Requires</b>: pos1 <= size()
//!
//! <b>Effects</b>: Determines the effective length rlen of the string to copy as
//! the smaller of
//! <b>Effects</b>: Determines the effective length rlen of the string to compare as
//! the smaller of (this->size() - pos1), n1 and str.size(). The function then compares the two strings by
//! calling traits::compare(data()+pos1, str.data(), rlen).
//!
//! <b>Throws</b>: out_of_range if pos1 > size()
//!
@ -2440,6 +2600,22 @@ class basic_string
str_addr, str_addr + str.priv_size());
}
//! <b>Requires</b>: pos1 <= size()
//!
//! <b>Throws</b>: out_of_range if pos1 > size()
//!
//! <b>Returns</b>:basic_string(*this,pos1,n1).compare(sv).
template<template <class, class> class BasicStringView>
int compare(size_type pos1, size_type n1, BasicStringView<CharT,Traits> sv) const
{
if (pos1 > this->size())
throw_out_of_range("basic_string::compare out of range position");
const pointer addr = this->priv_addr() + pos1;
const CharT* str_addr = sv.data();
return s_compare(addr, addr + container_detail::min_value(n1, this->size() - pos1),
str_addr, str_addr + sv.size());
}
//! <b>Requires</b>: pos1 <= size() and pos2 <= str.size()
//!
//! <b>Effects</b>: Determines the effective length rlen of the string to copy as
@ -2452,12 +2628,29 @@ class basic_string
{
if (pos1 > this->size() || pos2 > str.size())
throw_out_of_range("basic_string::compare out of range position");
const pointer addr = this->priv_addr();
const pointer str_addr = str.priv_addr();
return s_compare(addr + pos1,
addr + pos1 + container_detail::min_value(n1, this->size() - pos1),
str_addr + pos2,
str_addr + pos2 + container_detail::min_value(n2, str.size() - pos2));
const pointer addr = this->priv_addr() + pos1;
const pointer str_addr = str.priv_addr() + pos2;
return s_compare(addr, addr + container_detail::min_value(n1, this->size() - pos1),
str_addr, str_addr + container_detail::min_value(n2, str.size() - pos2));
}
//! <b>Requires</b>: pos1 <= size() and pos2 <= str.size()
//!
//! <b>Effects</b>: Determines the effective length rlen of the string to copy as
//! the smaller of
//!
//! <b>Throws</b>: out_of_range if pos1 > size() or pos2 > sv.size()
//!
//! <b>Returns</b>: basic_string(*this, pos1, n1).compare(BasicStringView<CharT, Traits>(sv, pos2, n2)).
template<template <class, class> class BasicStringView>
int compare(size_type pos1, size_type n1, BasicStringView<CharT,Traits> sv, size_type pos2, size_type n2) const
{
if (pos1 > this->size() || pos2 > sv.size())
throw_out_of_range("basic_string::compare out of range position");
const pointer addr = this->priv_addr() + pos1;
const CharT * str_addr = sv.data() + pos2;
return s_compare(addr, addr + container_detail::min_value(n1, this->size() - pos1),
str_addr, str_addr + container_detail::min_value(n2, sv.size() - pos2));
}
//! <b>Throws</b>: Nothing
@ -2469,17 +2662,6 @@ class basic_string
return s_compare(addr, addr + this->priv_size(), s, s + Traits::length(s));
}
//! <b>Throws</b>: Nothing
//!
//! <b>Returns</b>: compare(basic_string(sv)).
int compare(boost::basic_string_view<CharT,Traits> sv) const
{
const pointer addr = this->priv_addr();
return s_compare(addr, addr + this->priv_size(),
sv.data(), sv.data() + sv.size());
}
//! <b>Requires</b>: pos1 > size() and s points to an array of at least n2 elements of CharT.
//!
//! <b>Throws</b>: out_of_range if pos1 > size()
@ -2532,8 +2714,8 @@ class basic_string
}
}
static int s_compare(const_pointer f1, const_pointer l1,
const_pointer f2, const_pointer l2)
template<class It1, class It2>
static int s_compare(It1 f1, It1 l1, It2 f2, It2 l2)
{
const difference_type n1 = l1 - f1;
const difference_type n2 = l2 - f2;
@ -2770,8 +2952,7 @@ template <class CharT, class Traits, class Allocator> inline
template <class CharT, class Traits, class Allocator>
inline bool
operator==(const basic_string<CharT,Traits,Allocator>& x,
const basic_string<CharT,Traits,Allocator>& y)
operator==(const basic_string<CharT,Traits,Allocator>& x, const basic_string<CharT,Traits,Allocator>& y)
{
return x.size() == y.size() &&
Traits::compare(x.data(), y.data(), x.size()) == 0;
@ -2793,10 +2974,17 @@ operator==(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
return x.size() == n && Traits::compare(x.data(), s, n) == 0;
}
template <class CharT, class Traits, class Allocator>
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool
operator==( boost::basic_string_view<CharT,Traits> x,
const basic_string<CharT,Traits,Allocator>& y)
operator==( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
{
return x.size() == y.size() &&
Traits::compare(x.data(), y.data(), x.size()) == 0;
}
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool
operator==( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
{
return x.size() == y.size() &&
Traits::compare(x.data(), y.data(), x.size()) == 0;
@ -2804,18 +2992,7 @@ operator==( boost::basic_string_view<CharT,Traits> x,
template <class CharT, class Traits, class Allocator>
inline bool
operator==( const basic_string<CharT,Traits,Allocator>& x,
boost::basic_string_view<CharT,Traits> y)
{
return x.size() == y.size() &&
Traits::compare(x.data(), y.data(), x.size()) == 0;
}
template <class CharT, class Traits, class Allocator>
inline bool
operator!=(const basic_string<CharT,Traits,Allocator>& x,
const basic_string<CharT,Traits,Allocator>& y)
operator!=(const basic_string<CharT,Traits,Allocator>& x, const basic_string<CharT,Traits,Allocator>& y)
{ return !(x == y); }
template <class CharT, class Traits, class Allocator>
@ -2829,28 +3006,22 @@ operator!=(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
{ return !(x == s); }
template <class CharT, class Traits, class Allocator>
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool
operator!=( boost::basic_string_view<CharT,Traits> x,
const basic_string<CharT,Traits,Allocator>& y)
operator!=( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
{ return !(x == y); }
template <class CharT, class Traits, class Allocator>
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool
operator!=( const basic_string<CharT,Traits,Allocator>& x,
boost::basic_string_view<CharT,Traits> y)
operator!=( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
{ return !(x == y); }
// Operator< (and also >, <=, and >=).
template <class CharT, class Traits, class Allocator>
inline bool
operator<(const basic_string<CharT,Traits,Allocator>& x, const basic_string<CharT,Traits,Allocator>& y)
{
return x.compare(y) < 0;
// return basic_string<CharT,Traits,Allocator>
// ::s_compare(x.begin(), x.end(), y.begin(), y.end()) < 0;
}
template <class CharT, class Traits, class Allocator>
@ -2858,38 +3029,28 @@ inline bool
operator<(const CharT* s, const basic_string<CharT,Traits,Allocator>& y)
{
return y.compare(s) > 0;
// basic_string<CharT,Traits,Allocator>::size_type n = Traits::length(s);
// return basic_string<CharT,Traits,Allocator>
// ::s_compare(s, s + n, y.begin(), y.end()) < 0;
}
template <class CharT, class Traits, class Allocator>
inline bool
operator<(const basic_string<CharT,Traits,Allocator>& x,
const CharT* s)
operator<(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
{
return x.compare(s) < 0;
// basic_string<CharT,Traits,Allocator>::size_type n = Traits::length(s);
// return basic_string<CharT,Traits,Allocator>
// ::s_compare(x.begin(), x.end(), s, s + n) < 0;
}
template <class CharT, class Traits, class Allocator>
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool
operator<( boost::basic_string_view<CharT,Traits> x,
const basic_string<CharT,Traits,Allocator>& y)
operator<( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
{ return y.compare(x) > 0; }
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool
operator<( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
{ return x.compare(y) < 0; }
template <class CharT, class Traits, class Allocator>
inline bool
operator<( const basic_string<CharT,Traits,Allocator>& x,
boost::basic_string_view<CharT,Traits> y)
{ return y.compare(x) > 0; }
template <class CharT, class Traits, class Allocator>
inline bool
operator>(const basic_string<CharT,Traits,Allocator>& x,
const basic_string<CharT,Traits,Allocator>& y) {
operator>(const basic_string<CharT,Traits,Allocator>& x, const basic_string<CharT,Traits,Allocator>& y) {
return y < x;
}
@ -2906,23 +3067,19 @@ operator>(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
return s < x;
}
template <class CharT, class Traits, class Allocator>
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool
operator>( boost::basic_string_view<CharT,Traits> x,
const basic_string<CharT,Traits,Allocator>& y)
operator>( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
{ return y < x; }
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool
operator>( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
{ return y < x; }
template <class CharT, class Traits, class Allocator>
inline bool
operator>( const basic_string<CharT,Traits,Allocator>& x,
boost::basic_string_view<CharT,Traits> y)
{ return y < x; }
template <class CharT, class Traits, class Allocator>
inline bool
operator<=(const basic_string<CharT,Traits,Allocator>& x,
const basic_string<CharT,Traits,Allocator>& y)
operator<=(const basic_string<CharT,Traits,Allocator>& x, const basic_string<CharT,Traits,Allocator>& y)
{
return !(y < x);
}
@ -2938,16 +3095,14 @@ operator<=(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
{ return !(s < x); }
template <class CharT, class Traits, class Allocator>
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool
operator<=( boost::basic_string_view<CharT,Traits> x,
const basic_string<CharT,Traits,Allocator>& y)
operator<=( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
{ return !(y < x); }
template <class CharT, class Traits, class Allocator>
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool
operator<=( const basic_string<CharT,Traits,Allocator>& x,
boost::basic_string_view<CharT,Traits> y)
operator<=( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
{ return !(y < x); }
template <class CharT, class Traits, class Allocator>
@ -2966,19 +3121,16 @@ inline bool
operator>=(const basic_string<CharT,Traits,Allocator>& x, const CharT* s)
{ return !(x < s); }
template <class CharT, class Traits, class Allocator>
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool
operator>=( boost::basic_string_view<CharT,Traits> x,
const basic_string<CharT,Traits,Allocator>& y)
operator>=( BasicStringView<CharT,Traits> x, const basic_string<CharT,Traits,Allocator>& y)
{ return !(x < y); }
template <class CharT, class Traits, class Allocator>
template <class CharT, class Traits, class Allocator, template <class, class> class BasicStringView>
inline bool
operator>=( const basic_string<CharT,Traits,Allocator>& x,
boost::basic_string_view<CharT,Traits> y)
operator>=( const basic_string<CharT,Traits,Allocator>& x, BasicStringView<CharT,Traits> y)
{ return !(x < y); }
// Swap.
template <class CharT, class Traits, class Allocator>
inline void swap(basic_string<CharT,Traits,Allocator>& x, basic_string<CharT,Traits,Allocator>& y)

View File

@ -307,6 +307,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "node_handle_test", "node_ha
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "string_view_compat_test", "string_view_compat_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D4A792607}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
@ -621,6 +625,10 @@ Global
{5A17C6C5-6C29-A74F-48FE-A7FA7A063106}.Debug.Build.0 = Debug|Win32
{5A17C6C5-6C29-A74F-48FE-A7FA7A063106}.Release.ActiveCfg = Release|Win32
{5A17C6C5-6C29-A74F-48FE-A7FA7A063106}.Release.Build.0 = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D4A792607}.Debug.ActiveCfg = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D4A792607}.Debug.Build.0 = Debug|Win32
{58CCE183-6092-48FE-A4F7-BA0D4A792607}.Release.ActiveCfg = Release|Win32
{58CCE183-6092-48FE-A4F7-BA0D4A792607}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection

View File

@ -245,9 +245,6 @@
<File
RelativePath="..\..\..\..\boost\container\detail\function_detector.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\hash_table.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\container\detail\is_sorted.hpp">
</File>

View File

@ -0,0 +1,136 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="string_view_compat_test"
ProjectGUID="{58CCE183-6092-48FE-A4F7-BA0D4A792607}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/string_view_compat_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
GeneratePreprocessedFile="0"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/string_view_compat_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/string_view_compat_test.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"
/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/string_view_compat_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
TreatWChar_tAsBuiltInType="TRUE"
ForceConformanceInForLoopScope="FALSE"
UsePrecompiledHeader="0"
WarningLevel="4"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/string_view_compat_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath="..\..\test\string_view_compat_test.cpp">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -25,6 +25,7 @@
#include "propagate_allocator_test.hpp"
#include "default_init_test.hpp"
#include "../../intrusive/test/iterator_test.hpp"
#include <boost/utility/string_view.hpp>
using namespace boost::container;
@ -546,20 +547,14 @@ int main()
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);
if(boost::report_errors() != 0) {
return 1;
}
}
{
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);
if(boost::report_errors() != 0) {
return 1;
}
}
return 0;
return boost::report_errors();
}
#include <boost/container/detail/config_end.hpp>

View File

@ -0,0 +1,275 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2007-2017. 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/string.hpp>
#include <boost/utility/string_view.hpp>
#include <boost/core/lightweight_test.hpp>
void conversion_test()
{
#ifndef BOOST_CONTAINER_TEMPLATED_CONVERSION_OPERATOR_BROKEN
{
const boost::container::string s = "some text";
boost::string_view sv(s);
BOOST_TEST(s.data() == sv.data() && s.size() == sv.size());
boost::string_view sv2;
sv2 = s;
BOOST_TEST(s.data() == sv2.data() && s.size() == sv2.size());
const boost::string_view csv(s);
BOOST_TEST(s.data() == sv.data() && s.size() == csv.size());
}
#endif
}
void to_view_test()
{
const boost::container::string s = "some text";
boost::string_view sv(s.to_view<boost::string_view>());
BOOST_TEST(s.data() == sv.data() && s.size() == sv.size());
boost::string_view sv2;
sv2 = s.to_view<boost::string_view>();
BOOST_TEST(s.data() == sv2.data() && s.size() == sv2.size());
const boost::string_view csv(s.to_view<boost::string_view>());
BOOST_TEST(s.data() == csv.data() && s.size() == csv.size());
}
void equal_test()
{
const boost::string_view sv = "same text";
const boost::string_view svd = "different text";
const boost::container::string s = "same text";
BOOST_TEST(sv == s);
BOOST_TEST(s == sv);
BOOST_TEST(!(svd == s));
BOOST_TEST(!(s == svd));
}
void unequal_test()
{
const boost::string_view sv = "same text";
const boost::string_view svd = "different text";
const boost::container::string s = "same text";
BOOST_TEST(!(sv != s));
BOOST_TEST(!(s != sv));
BOOST_TEST(svd != s);
BOOST_TEST(s != svd);
}
void less_test()
{
boost::string_view sv = "0123456";
boost::container::string s = "0123459";
BOOST_TEST(sv < s);
BOOST_TEST(!(s < sv));
sv = "0123459";
s = "0123456";
BOOST_TEST(!(sv < s));
BOOST_TEST(s < sv);
sv = "0123456";
BOOST_TEST(!(sv < s));
BOOST_TEST(!(s < sv));
}
void greater_test()
{
boost::string_view sv = "0123459";
boost::container::string s = "0123456";
BOOST_TEST(sv > s);
BOOST_TEST(!(s > sv));
sv = "0123456";
s = "0123459";
BOOST_TEST(!(sv > s));
BOOST_TEST(s > sv);
sv = "0123459";
BOOST_TEST(!(sv > s));
BOOST_TEST(!(s > sv));
}
void less_equal_test()
{
boost::string_view sv = "0123456";
boost::container::string s = "0123459";
BOOST_TEST(sv <= s);
BOOST_TEST(!(s <= sv));
sv = "0123459";
s = "0123456";
BOOST_TEST(!(sv <= s));
BOOST_TEST(s <= sv);
sv = "0123456";
BOOST_TEST(sv <= s);
BOOST_TEST(s <= sv);
}
void greater_equal_test()
{
boost::string_view sv = "0123459";
boost::container::string s = "0123456";
BOOST_TEST(sv >= s);
BOOST_TEST(!(s >= sv));
sv = "0123456";
s = "0123459";
BOOST_TEST(!(sv >= s));
BOOST_TEST(s >= sv);
sv = "0123459";
BOOST_TEST(sv >= s);
BOOST_TEST(s >= sv);
}
void constructor_test()
{
boost::string_view sv = "0123459";
boost::container::string s(sv);
BOOST_TEST(sv == s);
boost::container::string s2(sv, s.get_allocator());
BOOST_TEST(sv == s);
}
void assignment_test()
{
boost::string_view sv = "0123459";
boost::container::string s;
s = sv;
BOOST_TEST(sv == s);
}
void assign_test()
{
boost::string_view sv = "0123459";
boost::container::string s;
s.assign(sv);
BOOST_TEST(sv == s);
}
void plus_equal_test()
{
boost::string_view sv = "23459";
boost::container::string s("01");
s += sv;
BOOST_TEST(s == "0123459");
}
void append_test()
{
boost::string_view sv = "23459";
boost::container::string s("01");
s.append(sv);
BOOST_TEST(s == "0123459");
}
void insert_test()
{
boost::string_view sv = "34";
boost::container::string s("01259");
s.insert(3u, sv);
BOOST_TEST(s == "0123459");
}
void replace_test()
{
boost::string_view sv = "5678";
boost::container::string s("01259");
s.replace(2u, 2u, sv);
BOOST_TEST(s == "0156789");
s.replace(s.begin()+3, s.begin()+6, sv);
BOOST_TEST(s == "01556789");
s.replace(5u, 3u, sv, 2u, 2u);
BOOST_TEST(s == "0155678");
}
void find_test()
{
const boost::string_view sv = "25";
boost::container::string s("0125925123");
BOOST_TEST(s.find(sv,4) == 5);
}
void rfind_test()
{
const boost::string_view sv = "25";
boost::container::string s("0125925123");
BOOST_TEST(s.rfind(sv,4) == 2);
}
void find_first_of_test()
{
const boost::string_view sv = "52";
boost::container::string s("0125925123");
BOOST_TEST(s.find_first_of(sv,4) == 5);
}
void find_last_of_test()
{
const boost::string_view sv = "52";
boost::container::string s("520125925123");
BOOST_TEST(s.find_last_of(sv,6) == 5);
}
void find_first_not_of_test()
{
const boost::string_view sv = "52";
boost::container::string s("0125925123");
BOOST_TEST(s.find_first_not_of(sv,2) == 4);
}
void find_last_not_of_test()
{
const boost::string_view sv = "52";
boost::container::string s("0125925123");
BOOST_TEST(s.find_last_not_of(sv,6) == 4);
}
void compare_test()
{
const boost::string_view sv = "52";
boost::container::string s("0125925123");
BOOST_TEST(s.compare(sv) < 0);
BOOST_TEST(s.compare(boost::string_view("0125925123")) == 0);
BOOST_TEST(s.compare(2u, s.size() - 2u, boost::string_view("25925123")) == 0);
boost::string_view sv2("5212592512389");
BOOST_TEST(s.compare(2u, s.size() - 2u, sv2, 3, sv2.size()-5u) == 0);
}
int main()
{
conversion_test();
to_view_test();
equal_test();
unequal_test();
less_test();
greater_test();
less_equal_test();
greater_equal_test();
constructor_test();
assignment_test();
assign_test();
plus_equal_test();
append_test();
insert_test();
replace_test();
find_test();
rfind_test();
find_first_of_test();
find_last_of_test();
find_first_not_of_test();
find_last_not_of_test();
compare_test();
return boost::report_errors();
}