diff --git a/doc/string_view.qbk b/doc/string_view.qbk index 4c6fc79..4434660 100644 --- a/doc/string_view.qbk +++ b/doc/string_view.qbk @@ -5,7 +5,7 @@ / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) /] -[article String_Ref +[article String_View [quickbook 1.5] [authors [Clow, Marshall]] [copyright 2012 Marshall Clow] @@ -20,8 +20,8 @@ [section Overview] [/===============] -Boost.StringRef is an implementation of Jeffrey Yaskin's [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html N3442: -string_ref: a non-owning reference to a string]. +Boost.StringView is an implementation of Jeffrey Yaskin's [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html N3442: +string_view: a non-owning reference to a string]. When you are parsing/processing strings from some external source, frequently you want to pass a piece of text to a procedure for specialized processing. The canonical way to do this is as a `std::string`, but that has certain drawbacks: @@ -31,15 +31,15 @@ When you are parsing/processing strings from some external source, frequently yo 3) A routine receives a constant `std::string` and wants to return a portion of the string, then it must create a new string to return. -`string_ref` is designed to solve these efficiency problems. A `string_ref` is a read-only reference to a contiguous sequence of characters, and provides much of the functionality of `std::string`. A `string_ref` is cheap to create, copy and pass by value, because it does not actually own the storage that it points to. +`string_view` is designed to solve these efficiency problems. A `string_view` is a read-only reference to a contiguous sequence of characters, and provides much of the functionality of `std::string`. A `string_view` is cheap to create, copy and pass by value, because it does not actually own the storage that it points to. -A `string_ref` is implemented as a small struct that contains a pointer to the start of the character data and a count. A `string_ref` is cheap to create and cheap to copy. +A `string_view` is implemented as a small struct that contains a pointer to the start of the character data and a count. A `string_view` is cheap to create and cheap to copy. -`string_ref` acts as a container; it includes all the methods that you would expect in a container, including iteration support, `operator []`, `at` and `size`. It can be used with any of the iterator-based algorithms in the STL - as long as you don't need to change the underlying data (`sort` and `remove`, for example, will not work) +`string_view` acts as a container; it includes all the methods that you would expect in a container, including iteration support, `operator []`, `at` and `size`. It can be used with any of the iterator-based algorithms in the STL - as long as you don't need to change the underlying data (`sort` and `remove`, for example, will not work) -Besides generic container functionality, `string_ref` provides a subset of the interface of `std::string`. This makes it easy to replace parameters of type `const std::string &` with `boost::string_ref`. Like `std::string`, `string_ref` has a static member variable named `npos` to denote the result of failed searches, and to mean "the end". +Besides generic container functionality, `string_view` provides a subset of the interface of `std::string`. This makes it easy to replace parameters of type `const std::string &` with `boost::string_view`. Like `std::string`, `string_view` has a static member variable named `npos` to denote the result of failed searches, and to mean "the end". -Because a `string_ref` does not own the data that it "points to", it introduces lifetime issues into code that uses it. The programmer must ensure that the data that a `string_ref` refers to exists as long as the `string_ref` does. +Because a `string_view` does not own the data that it "points to", it introduces lifetime issues into code that uses it. The programmer must ensure that the data that a `string_view` refers to exists as long as the `string_view` does. [endsect] @@ -48,7 +48,7 @@ Because a `string_ref` does not own the data that it "points to", it introduces [section Examples] [/===============] -Integrating `string_ref` into your code is fairly simple. Wherever you pass a `const std::string &` or `std::string` as a parameter, that's a candidate for passing a `boost::string_ref`. +Integrating `string_view` into your code is fairly simple. Wherever you pass a `const std::string &` or `std::string` as a parameter, that's a candidate for passing a `boost::string_view`. std::string extract_part ( const std::string &bar ) { return bar.substr ( 2, 3 ); @@ -62,15 +62,15 @@ First, a temporary string is created from the string literal `"ABCDEFG"`, and it Two `std::string`s are created, and two copy operations. That's (potentially) four memory allocations and deallocations, and the associated copying of data. -Now let's look at the same code with `string_ref`: +Now let's look at the same code with `string_view`: - boost::string_ref extract_part ( boost::string_ref bar ) { + boost::string_view extract_part ( boost::string_view bar ) { return bar.substr ( 2, 3 ); } if ( extract_part ( "ABCDEFG" ).front() == "C" ) { /* do something */ } -No memory allocations. No copying of character data. No changes to the code other than the types. There are two `string_ref`s created, and two `string_ref`s copied, but those are cheap operations. +No memory allocations. No copying of character data. No changes to the code other than the types. There are two `string_view`s created, and two `string_view`s copied, but those are cheap operations. [endsect] @@ -79,21 +79,21 @@ No memory allocations. No copying of character data. No changes to the code othe [section:reference Reference ] [/=================] -The header file "string_ref.hpp" defines a template `boost::basic_string_ref`, and four specializations - for `char` / `wchar_t` / `char16_t` / `char32_t` . +The header file "string_view.hpp" defines a template `boost::basic_string_view`, and four specializations - for `char` / `wchar_t` / `char16_t` / `char32_t` . -`#include ` +`#include ` Construction and copying: - BOOST_CONSTEXPR basic_string_ref (); // Constructs an empty string_ref - BOOST_CONSTEXPR basic_string_ref(const charT* str); // Constructs from a NULL-terminated string - BOOST_CONSTEXPR basic_string_ref(const charT* str, size_type len); // Constructs from a pointer, length pair + BOOST_CONSTEXPR basic_string_view (); // Constructs an empty string_view + BOOST_CONSTEXPR basic_string_view(const charT* str); // Constructs from a NULL-terminated string + BOOST_CONSTEXPR basic_string_view(const charT* str, size_type len); // Constructs from a pointer, length pair template - basic_string_ref(const std::basic_string& str); // Constructs from a std::string - basic_string_ref (const basic_string_ref &rhs); - basic_string_ref& operator=(const basic_string_ref &rhs); + basic_string_view(const std::basic_string& str); // Constructs from a std::string + basic_string_view (const basic_string_view &rhs); + basic_string_view& operator=(const basic_string_view &rhs); -`string_ref` does not define a move constructor nor a move-assignment operator because copying a `string_ref` is just a cheap as moving one. +`string_view` does not define a move constructor nor a move-assignment operator because copying a `string_view` is just a cheap as moving one. Basic container-like functions: @@ -120,7 +120,7 @@ Access to the individual elements (all of which are const): BOOST_CONSTEXPR const charT& back() const ; BOOST_CONSTEXPR const charT* data() const ; -Modifying the `string_ref` (but not the underlying data): +Modifying the `string_view` (but not the underlying data): void clear(); void remove_prefix(size_type n); @@ -128,27 +128,27 @@ Modifying the `string_ref` (but not the underlying data): Searching: - size_type find(basic_string_ref s) const ; + size_type find(basic_string_view s) const ; size_type find(charT c) const ; - size_type rfind(basic_string_ref s) const ; + size_type rfind(basic_string_view s) const ; size_type rfind(charT c) const ; size_type find_first_of(charT c) const ; size_type find_last_of (charT c) const ; - size_type find_first_of(basic_string_ref s) const ; - size_type find_last_of(basic_string_ref s) const ; - size_type find_first_not_of(basic_string_ref s) const ; + size_type find_first_of(basic_string_view s) const ; + size_type find_last_of(basic_string_view s) const ; + size_type find_first_not_of(basic_string_view s) const ; size_type find_first_not_of(charT c) const ; - size_type find_last_not_of(basic_string_ref s) const ; + size_type find_last_not_of(basic_string_view s) const ; size_type find_last_not_of(charT c) const ; String-like operations: - BOOST_CONSTEXPR basic_string_ref substr(size_type pos, size_type n=npos) const ; // Creates a new string_ref + BOOST_CONSTEXPR basic_string_view substr(size_type pos, size_type n=npos) const ; // Creates a new string_view bool starts_with(charT c) const ; - bool starts_with(basic_string_ref x) const ; + bool starts_with(basic_string_view x) const ; bool ends_with(charT c) const ; - bool ends_with(basic_string_ref x) const ; + bool ends_with(basic_string_view x) const ; [endsect] diff --git a/include/boost/utility/string_view.hpp b/include/boost/utility/string_view.hpp index 8707157..927bd68 100644 --- a/include/boost/utility/string_view.hpp +++ b/include/boost/utility/string_view.hpp @@ -12,12 +12,12 @@ */ -#ifndef BOOST_STRING_REF_HPP -#define BOOST_STRING_REF_HPP +#ifndef BOOST_STRING_VIEW_HPP +#define BOOST_STRING_VIEW_HPP #include #include -#include +#include #include #include @@ -32,22 +32,23 @@ namespace boost { namespace detail { // A helper functor because sometimes we don't have lambdas template - class string_ref_traits_eq { + class string_view_traits_eq { public: - string_ref_traits_eq ( charT ch ) : ch_(ch) {} + string_view_traits_eq ( charT ch ) : ch_(ch) {} bool operator () ( charT val ) const { return traits::eq ( ch_, val ); } charT ch_; }; } template - class basic_string_ref { + class basic_string_view { public: // types + typedef traits traits_type; typedef charT value_type; typedef const charT* pointer; typedef const charT& reference; - typedef const charT& const_reference; + typedef const charT& const_viewerence; typedef pointer const_iterator; // impl-defined typedef const_iterator iterator; typedef std::reverse_iterator const_reverse_iterator; @@ -57,26 +58,26 @@ namespace boost { static BOOST_CONSTEXPR_OR_CONST size_type npos = size_type(-1); // construct/copy - BOOST_CONSTEXPR basic_string_ref () + BOOST_CONSTEXPR basic_string_view () : ptr_(NULL), len_(0) {} - BOOST_CONSTEXPR basic_string_ref (const basic_string_ref &rhs) + BOOST_CONSTEXPR basic_string_view (const basic_string_view &rhs) : ptr_(rhs.ptr_), len_(rhs.len_) {} - basic_string_ref& operator=(const basic_string_ref &rhs) { + basic_string_view& operator=(const basic_string_view &rhs) { ptr_ = rhs.ptr_; len_ = rhs.len_; return *this; } - basic_string_ref(const charT* str) + basic_string_view(const charT* str) : ptr_(str), len_(traits::length(str)) {} template - basic_string_ref(const std::basic_string& str) + basic_string_view(const std::basic_string& str) : ptr_(str.data()), len_(str.length()) {} - BOOST_CONSTEXPR basic_string_ref(const charT* str, size_type len) + BOOST_CONSTEXPR basic_string_view(const charT* str, size_type len) : ptr_(str), len_(len) {} #ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS @@ -111,7 +112,7 @@ namespace boost { const charT& at(size_t pos) const { if ( pos >= len_ ) - BOOST_THROW_EXCEPTION( std::out_of_range ( "boost::string_ref::at" ) ); + BOOST_THROW_EXCEPTION( std::out_of_range ( "boost::string_view::at" ) ); return ptr_[pos]; } @@ -135,31 +136,31 @@ namespace boost { } - // basic_string_ref string operations - basic_string_ref substr(size_type pos, size_type n=npos) const { + // basic_string_view string operations + basic_string_view substr(size_type pos, size_type n=npos) const { if ( pos > size()) - BOOST_THROW_EXCEPTION( std::out_of_range ( "string_ref::substr" ) ); + BOOST_THROW_EXCEPTION( std::out_of_range ( "string_view::substr" ) ); if ( n == npos || pos + n > size()) n = size () - pos; - return basic_string_ref ( data() + pos, n ); + return basic_string_view ( data() + pos, n ); } - int compare(basic_string_ref x) const { + int compare(basic_string_view x) const { const int cmp = traits::compare ( ptr_, x.ptr_, (std::min)(len_, x.len_)); return cmp != 0 ? cmp : ( len_ == x.len_ ? 0 : len_ < x.len_ ? -1 : 1 ); } bool starts_with(charT c) const { return !empty() && traits::eq ( c, front()); } - bool starts_with(basic_string_ref x) const { + bool starts_with(basic_string_view x) const { return len_ >= x.len_ && traits::compare ( ptr_, x.ptr_, x.len_ ) == 0; } bool ends_with(charT c) const { return !empty() && traits::eq ( c, back()); } - bool ends_with(basic_string_ref x) const { + bool ends_with(basic_string_view x) const { return len_ >= x.len_ && traits::compare ( ptr_ + len_ - x.len_, x.ptr_, x.len_ ) == 0; } - size_type find(basic_string_ref s) const { + size_type find(basic_string_view s) const { const_iterator iter = std::search ( this->cbegin (), this->cend (), s.cbegin (), s.cend (), traits::eq ); return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter ); @@ -167,11 +168,11 @@ namespace boost { size_type find(charT c) const { const_iterator iter = std::find_if ( this->cbegin (), this->cend (), - detail::string_ref_traits_eq ( c )); + detail::string_view_traits_eq ( c )); return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter ); } - size_type rfind(basic_string_ref s) const { + size_type rfind(basic_string_view s) const { const_reverse_iterator iter = std::search ( this->crbegin (), this->crend (), s.crbegin (), s.crend (), traits::eq ); return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter ); @@ -179,26 +180,26 @@ namespace boost { size_type rfind(charT c) const { const_reverse_iterator iter = std::find_if ( this->crbegin (), this->crend (), - detail::string_ref_traits_eq ( c )); + detail::string_view_traits_eq ( c )); return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter ); } size_type find_first_of(charT c) const { return find (c); } size_type find_last_of (charT c) const { return rfind (c); } - size_type find_first_of(basic_string_ref s) const { + size_type find_first_of(basic_string_view s) const { const_iterator iter = std::find_first_of ( this->cbegin (), this->cend (), s.cbegin (), s.cend (), traits::eq ); return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter ); } - size_type find_last_of(basic_string_ref s) const { + size_type find_last_of(basic_string_view s) const { const_reverse_iterator iter = std::find_first_of ( this->crbegin (), this->crend (), s.cbegin (), s.cend (), traits::eq ); return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter); } - size_type find_first_not_of(basic_string_ref s) const { + size_type find_first_not_of(basic_string_view s) const { const_iterator iter = find_not_of ( this->cbegin (), this->cend (), s ); return iter == this->cend () ? npos : std::distance ( this->cbegin (), iter ); } @@ -210,7 +211,7 @@ namespace boost { return npos; } - size_type find_last_not_of(basic_string_ref s) const { + size_type find_last_not_of(basic_string_view s) const { const_reverse_iterator iter = find_not_of ( this->crbegin (), this->crend (), s ); return iter == this->crend () ? npos : reverse_distance ( this->crbegin (), iter ); } @@ -229,7 +230,7 @@ namespace boost { } template - Iterator find_not_of ( Iterator first, Iterator last, basic_string_ref s ) const { + Iterator find_not_of ( Iterator first, Iterator last, basic_string_view s ) const { for ( ; first != last ; ++first ) if ( 0 == traits::find ( s.ptr_, s.len_, *first )) return first; @@ -246,160 +247,160 @@ namespace boost { // Comparison operators // Equality template - inline bool operator==(basic_string_ref x, basic_string_ref y) { + inline bool operator==(basic_string_view x, basic_string_view y) { if ( x.size () != y.size ()) return false; return x.compare(y) == 0; } template - inline bool operator==(basic_string_ref x, const std::basic_string & y) { - return x == basic_string_ref(y); + inline bool operator==(basic_string_view x, const std::basic_string & y) { + return x == basic_string_view(y); } template - inline bool operator==(const std::basic_string & x, basic_string_ref y) { - return basic_string_ref(x) == y; + inline bool operator==(const std::basic_string & x, basic_string_view y) { + return basic_string_view(x) == y; } template - inline bool operator==(basic_string_ref x, const charT * y) { - return x == basic_string_ref(y); + inline bool operator==(basic_string_view x, const charT * y) { + return x == basic_string_view(y); } template - inline bool operator==(const charT * x, basic_string_ref y) { - return basic_string_ref(x) == y; + inline bool operator==(const charT * x, basic_string_view y) { + return basic_string_view(x) == y; } // Inequality template - inline bool operator!=(basic_string_ref x, basic_string_ref y) { + inline bool operator!=(basic_string_view x, basic_string_view y) { if ( x.size () != y.size ()) return true; return x.compare(y) != 0; } template - inline bool operator!=(basic_string_ref x, const std::basic_string & y) { - return x != basic_string_ref(y); + inline bool operator!=(basic_string_view x, const std::basic_string & y) { + return x != basic_string_view(y); } template - inline bool operator!=(const std::basic_string & x, basic_string_ref y) { - return basic_string_ref(x) != y; + inline bool operator!=(const std::basic_string & x, basic_string_view y) { + return basic_string_view(x) != y; } template - inline bool operator!=(basic_string_ref x, const charT * y) { - return x != basic_string_ref(y); + inline bool operator!=(basic_string_view x, const charT * y) { + return x != basic_string_view(y); } template - inline bool operator!=(const charT * x, basic_string_ref y) { - return basic_string_ref(x) != y; + inline bool operator!=(const charT * x, basic_string_view y) { + return basic_string_view(x) != y; } // Less than template - inline bool operator<(basic_string_ref x, basic_string_ref y) { + inline bool operator<(basic_string_view x, basic_string_view y) { return x.compare(y) < 0; } template - inline bool operator<(basic_string_ref x, const std::basic_string & y) { - return x < basic_string_ref(y); + inline bool operator<(basic_string_view x, const std::basic_string & y) { + return x < basic_string_view(y); } template - inline bool operator<(const std::basic_string & x, basic_string_ref y) { - return basic_string_ref(x) < y; + inline bool operator<(const std::basic_string & x, basic_string_view y) { + return basic_string_view(x) < y; } template - inline bool operator<(basic_string_ref x, const charT * y) { - return x < basic_string_ref(y); + inline bool operator<(basic_string_view x, const charT * y) { + return x < basic_string_view(y); } template - inline bool operator<(const charT * x, basic_string_ref y) { - return basic_string_ref(x) < y; + inline bool operator<(const charT * x, basic_string_view y) { + return basic_string_view(x) < y; } // Greater than template - inline bool operator>(basic_string_ref x, basic_string_ref y) { + inline bool operator>(basic_string_view x, basic_string_view y) { return x.compare(y) > 0; } template - inline bool operator>(basic_string_ref x, const std::basic_string & y) { - return x > basic_string_ref(y); + inline bool operator>(basic_string_view x, const std::basic_string & y) { + return x > basic_string_view(y); } template - inline bool operator>(const std::basic_string & x, basic_string_ref y) { - return basic_string_ref(x) > y; + inline bool operator>(const std::basic_string & x, basic_string_view y) { + return basic_string_view(x) > y; } template - inline bool operator>(basic_string_ref x, const charT * y) { - return x > basic_string_ref(y); + inline bool operator>(basic_string_view x, const charT * y) { + return x > basic_string_view(y); } template - inline bool operator>(const charT * x, basic_string_ref y) { - return basic_string_ref(x) > y; + inline bool operator>(const charT * x, basic_string_view y) { + return basic_string_view(x) > y; } // Less than or equal to template - inline bool operator<=(basic_string_ref x, basic_string_ref y) { + inline bool operator<=(basic_string_view x, basic_string_view y) { return x.compare(y) <= 0; } template - inline bool operator<=(basic_string_ref x, const std::basic_string & y) { - return x <= basic_string_ref(y); + inline bool operator<=(basic_string_view x, const std::basic_string & y) { + return x <= basic_string_view(y); } template - inline bool operator<=(const std::basic_string & x, basic_string_ref y) { - return basic_string_ref(x) <= y; + inline bool operator<=(const std::basic_string & x, basic_string_view y) { + return basic_string_view(x) <= y; } template - inline bool operator<=(basic_string_ref x, const charT * y) { - return x <= basic_string_ref(y); + inline bool operator<=(basic_string_view x, const charT * y) { + return x <= basic_string_view(y); } template - inline bool operator<=(const charT * x, basic_string_ref y) { - return basic_string_ref(x) <= y; + inline bool operator<=(const charT * x, basic_string_view y) { + return basic_string_view(x) <= y; } // Greater than or equal to template - inline bool operator>=(basic_string_ref x, basic_string_ref y) { + inline bool operator>=(basic_string_view x, basic_string_view y) { return x.compare(y) >= 0; } template - inline bool operator>=(basic_string_ref x, const std::basic_string & y) { - return x >= basic_string_ref(y); + inline bool operator>=(basic_string_view x, const std::basic_string & y) { + return x >= basic_string_view(y); } template - inline bool operator>=(const std::basic_string & x, basic_string_ref y) { - return basic_string_ref(x) >= y; + inline bool operator>=(const std::basic_string & x, basic_string_view y) { + return basic_string_view(x) >= y; } template - inline bool operator>=(basic_string_ref x, const charT * y) { - return x >= basic_string_ref(y); + inline bool operator>=(basic_string_view x, const charT * y) { + return x >= basic_string_view(y); } template - inline bool operator>=(const charT * x, basic_string_ref y) { - return basic_string_ref(x) >= y; + inline bool operator>=(const charT * x, basic_string_view y) { + return basic_string_view(x) >= y; } namespace detail { @@ -416,7 +417,7 @@ namespace boost { } template - void insert_aligned(std::basic_ostream& os, const basic_string_ref& str) { + void insert_aligned(std::basic_ostream& os, const basic_string_view& str) { const std::size_t size = str.size(); const std::size_t alignment_size = static_cast< std::size_t >(os.width()) - size; const bool align_left = (os.flags() & std::basic_ostream::adjustfield) == std::basic_ostream::left; @@ -437,7 +438,7 @@ namespace boost { // Inserter template inline std::basic_ostream& - operator<<(std::basic_ostream& os, const basic_string_ref& str) { + operator<<(std::basic_ostream& os, const basic_string_view& str) { if (os.good()) { const std::size_t size = str.size(); const std::size_t w = static_cast< std::size_t >(os.width()); @@ -456,67 +457,67 @@ namespace boost { // These are short-term implementations. // In a production environment, I would rather avoid the copying. // - inline int stoi (string_ref str, size_t* idx=0, int base=10) { + inline int stoi (string_view str, size_t* idx=0, int base=10) { return std::stoi ( std::string(str), idx, base ); } - inline long stol (string_ref str, size_t* idx=0, int base=10) { + inline long stol (string_view str, size_t* idx=0, int base=10) { return std::stol ( std::string(str), idx, base ); } - inline unsigned long stoul (string_ref str, size_t* idx=0, int base=10) { + inline unsigned long stoul (string_view str, size_t* idx=0, int base=10) { return std::stoul ( std::string(str), idx, base ); } - inline long long stoll (string_ref str, size_t* idx=0, int base=10) { + inline long long stoll (string_view str, size_t* idx=0, int base=10) { return std::stoll ( std::string(str), idx, base ); } - inline unsigned long long stoull (string_ref str, size_t* idx=0, int base=10) { + inline unsigned long long stoull (string_view str, size_t* idx=0, int base=10) { return std::stoull ( std::string(str), idx, base ); } - inline float stof (string_ref str, size_t* idx=0) { + inline float stof (string_view str, size_t* idx=0) { return std::stof ( std::string(str), idx ); } - inline double stod (string_ref str, size_t* idx=0) { + inline double stod (string_view str, size_t* idx=0) { return std::stod ( std::string(str), idx ); } - inline long double stold (string_ref str, size_t* idx=0) { + inline long double stold (string_view str, size_t* idx=0) { return std::stold ( std::string(str), idx ); } - inline int stoi (wstring_ref str, size_t* idx=0, int base=10) { + inline int stoi (wstring_view str, size_t* idx=0, int base=10) { return std::stoi ( std::wstring(str), idx, base ); } - inline long stol (wstring_ref str, size_t* idx=0, int base=10) { + inline long stol (wstring_view str, size_t* idx=0, int base=10) { return std::stol ( std::wstring(str), idx, base ); } - inline unsigned long stoul (wstring_ref str, size_t* idx=0, int base=10) { + inline unsigned long stoul (wstring_view str, size_t* idx=0, int base=10) { return std::stoul ( std::wstring(str), idx, base ); } - inline long long stoll (wstring_ref str, size_t* idx=0, int base=10) { + inline long long stoll (wstring_view str, size_t* idx=0, int base=10) { return std::stoll ( std::wstring(str), idx, base ); } - inline unsigned long long stoull (wstring_ref str, size_t* idx=0, int base=10) { + inline unsigned long long stoull (wstring_view str, size_t* idx=0, int base=10) { return std::stoull ( std::wstring(str), idx, base ); } - inline float stof (wstring_ref str, size_t* idx=0) { + inline float stof (wstring_view str, size_t* idx=0) { return std::stof ( std::wstring(str), idx ); } - inline double stod (wstring_ref str, size_t* idx=0) { + inline double stod (wstring_view str, size_t* idx=0) { return std::stod ( std::wstring(str), idx ); } - inline long double stold (wstring_ref str, size_t* idx=0) { + inline long double stold (wstring_view str, size_t* idx=0) { return std::stold ( std::wstring(str), idx ); } #endif @@ -526,10 +527,10 @@ namespace boost { #if 0 namespace std { // Hashing - template<> struct hash; - template<> struct hash; - template<> struct hash; - template<> struct hash; + template<> struct hash; + template<> struct hash; + template<> struct hash; + template<> struct hash; } #endif diff --git a/include/boost/utility/string_view_fwd.hpp b/include/boost/utility/string_view_fwd.hpp index f58b98c..18ae6c6 100644 --- a/include/boost/utility/string_view_fwd.hpp +++ b/include/boost/utility/string_view_fwd.hpp @@ -12,24 +12,24 @@ */ -#ifndef BOOST_STRING_REF_FWD_HPP -#define BOOST_STRING_REF_FWD_HPP +#ifndef BOOST_STRING_VIEW_FWD_HPP +#define BOOST_STRING_VIEW_FWD_HPP #include #include namespace boost { - template > class basic_string_ref; - typedef basic_string_ref > string_ref; - typedef basic_string_ref > wstring_ref; + template > class basic_string_view; + typedef basic_string_view > string_view; + typedef basic_string_view > wstring_view; #ifndef BOOST_NO_CXX11_CHAR16_T - typedef basic_string_ref > u16string_ref; + typedef basic_string_view > u16string_view; #endif #ifndef BOOST_NO_CXX11_CHAR32_T - typedef basic_string_ref > u32string_ref; + typedef basic_string_view > u32string_view; #endif } diff --git a/test/msvc/common.props b/test/msvc/common.props new file mode 100644 index 0000000..8ce6a69 --- /dev/null +++ b/test/msvc/common.props @@ -0,0 +1,15 @@ + + + + + + + + ../../../../.. + + + "$(TargetDir)\$(TargetName).exe" + + + + \ No newline at end of file diff --git a/test/msvc/string_view.sln b/test/msvc/string_view.sln new file mode 100644 index 0000000..1a3465d --- /dev/null +++ b/test/msvc/string_view.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.22823.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "string_view_test3", "string_view_test3\string_view_test3.vcxproj", "{4921E3AB-4466-4592-BA7A-3460AD616956}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4921E3AB-4466-4592-BA7A-3460AD616956}.Debug|x86.ActiveCfg = Debug|Win32 + {4921E3AB-4466-4592-BA7A-3460AD616956}.Debug|x86.Build.0 = Debug|Win32 + {4921E3AB-4466-4592-BA7A-3460AD616956}.Release|x86.ActiveCfg = Release|Win32 + {4921E3AB-4466-4592-BA7A-3460AD616956}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/test/msvc/string_view_test3/string_view_test3.vcxproj b/test/msvc/string_view_test3/string_view_test3.vcxproj new file mode 100644 index 0000000..9f251f0 --- /dev/null +++ b/test/msvc/string_view_test3/string_view_test3.vcxproj @@ -0,0 +1,90 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {4921E3AB-4466-4592-BA7A-3460AD616956} + Win32Proj + string_view_test3 + + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + true + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/test/string_view_test1.cpp b/test/string_view_test1.cpp index f1d4df2..a8b0cd0 100644 --- a/test/string_view_test1.cpp +++ b/test/string_view_test1.cpp @@ -11,15 +11,15 @@ #include #include -#include +#include #define BOOST_TEST_MAIN #include -typedef boost::string_ref string_ref; +typedef boost::string_view string_view; // Should be equal -void interop ( const std::string &str, string_ref ref ) { +void interop ( const std::string &str, string_view ref ) { // BOOST_CHECK ( str == ref ); BOOST_CHECK ( str.size () == ref.size ()); BOOST_CHECK ( std::equal ( str.begin (), str.end (), ref.begin ())); @@ -28,10 +28,10 @@ void interop ( const std::string &str, string_ref ref ) { void null_tests ( const char *p ) { // All zero-length string-refs should be equal - string_ref sr1; // NULL, 0 - string_ref sr2 ( NULL, 0 ); - string_ref sr3 ( p, 0 ); - string_ref sr4 ( p ); + string_view sr1; // NULL, 0 + string_view sr2 ( NULL, 0 ); + string_view sr3 ( p, 0 ); + string_view sr4 ( p ); sr4.clear (); BOOST_CHECK ( sr1 == sr2 ); @@ -43,7 +43,7 @@ void null_tests ( const char *p ) { // make sure that substrings work just like strings void test_substr ( const std::string &str ) { const size_t sz = str.size (); - string_ref ref ( str ); + string_view ref ( str ); // Substrings at the end for ( size_t i = 0; i <= sz; ++ i ) @@ -63,7 +63,7 @@ void test_substr ( const std::string &str ) { void test_remove ( const std::string &str ) { const size_t sz = str.size (); std::string work; - string_ref ref; + string_view ref; for ( size_t i = 1; i <= sz; ++i ) { work = str; diff --git a/test/string_view_test2.cpp b/test/string_view_test2.cpp index 9559c67..86c96e1 100644 --- a/test/string_view_test2.cpp +++ b/test/string_view_test2.cpp @@ -10,17 +10,17 @@ #include #include // for std::strchr -#include +#include #define BOOST_TEST_MAIN #include -typedef boost::string_ref string_ref; +typedef boost::string_view string_view; void ends_with ( const char *arg ) { const size_t sz = std::strlen ( arg ); - string_ref sr ( arg ); - string_ref sr2 ( arg ); + string_view sr ( arg ); + string_view sr2 ( arg ); const char *p = arg; while ( *p ) { @@ -44,13 +44,13 @@ void ends_with ( const char *arg ) { if ( sz > 0 ) BOOST_CHECK ( sr2.ends_with ( ch )); BOOST_CHECK ( !sr2.ends_with ( ++ch )); - BOOST_CHECK ( sr2.ends_with ( string_ref ())); + BOOST_CHECK ( sr2.ends_with ( string_view ())); } void starts_with ( const char *arg ) { const size_t sz = std::strlen ( arg ); - string_ref sr ( arg ); - string_ref sr2 ( arg ); + string_view sr ( arg ); + string_view sr2 ( arg ); const char *p = arg + std::strlen ( arg ) - 1; while ( p >= arg ) { std::string foo ( arg, p + 1 ); @@ -68,14 +68,14 @@ void starts_with ( const char *arg ) { if ( sz > 0 ) BOOST_CHECK ( sr2.starts_with ( ch )); BOOST_CHECK ( !sr2.starts_with ( ++ch )); - BOOST_CHECK ( sr2.starts_with ( string_ref ())); + BOOST_CHECK ( sr2.starts_with ( string_view ())); } void reverse ( const char *arg ) { // Round trip - string_ref sr1 ( arg ); + string_view sr1 ( arg ); std::string string1 ( sr1.rbegin (), sr1.rend ()); - string_ref sr2 ( string1 ); + string_view sr2 ( string1 ); std::string string2 ( sr2.rbegin (), sr2.rend ()); BOOST_CHECK ( std::equal ( sr2.rbegin (), sr2.rend (), arg )); @@ -84,22 +84,22 @@ void reverse ( const char *arg ) { } // This helper function eliminates signed vs. unsigned warnings -string_ref::size_type ptr_diff ( const char *res, const char *base ) { +string_view::size_type ptr_diff ( const char *res, const char *base ) { BOOST_CHECK ( res >= base ); - return static_cast ( res - base ); + return static_cast ( res - base ); } void find ( const char *arg ) { - string_ref sr1; - string_ref sr2; + string_view sr1; + string_view sr2; const char *p; // Look for each character in the string(searching from the start) p = arg; sr1 = arg; while ( *p ) { - string_ref::size_type pos = sr1.find(*p); - BOOST_CHECK ( pos != string_ref::npos && ( pos <= ptr_diff ( p, arg ))); + string_view::size_type pos = sr1.find(*p); + BOOST_CHECK ( pos != string_view::npos && ( pos <= ptr_diff ( p, arg ))); ++p; } @@ -107,8 +107,8 @@ void find ( const char *arg ) { p = arg; sr1 = arg; while ( *p ) { - string_ref::size_type pos = sr1.rfind(*p); - BOOST_CHECK ( pos != string_ref::npos && pos < sr1.size () && ( pos >= ptr_diff ( p, arg ))); + string_view::size_type pos = sr1.rfind(*p); + BOOST_CHECK ( pos != string_view::npos && pos < sr1.size () && ( pos >= ptr_diff ( p, arg ))); ++p; } @@ -116,9 +116,9 @@ void find ( const char *arg ) { sr1 = arg; p = arg; while ( *p && *(p+1)) { - string_ref sr3 ( p, 2 ); - string_ref::size_type pos = sr1.find ( sr3 ); - BOOST_CHECK ( pos != string_ref::npos && pos <= static_cast( p - arg )); + string_view sr3 ( p, 2 ); + string_view::size_type pos = sr1.find ( sr3 ); + BOOST_CHECK ( pos != string_view::npos && pos <= static_cast( p - arg )); p++; } @@ -127,9 +127,9 @@ void find ( const char *arg ) { // for all possible chars, see if we find them in the right place. // Note that strchr will/might do the _wrong_ thing if we search for NULL for ( int ch = 1; ch < 256; ++ch ) { - string_ref::size_type pos = sr1.find(ch); + string_view::size_type pos = sr1.find(ch); const char *strp = std::strchr ( arg, ch ); - BOOST_CHECK (( strp == NULL ) == ( pos == string_ref::npos )); + BOOST_CHECK (( strp == NULL ) == ( pos == string_view::npos )); if ( strp != NULL ) BOOST_CHECK ( ptr_diff ( strp, arg ) == pos ); } @@ -139,9 +139,9 @@ void find ( const char *arg ) { // for all possible chars, see if we find them in the right place. // Note that strchr will/might do the _wrong_ thing if we search for NULL for ( int ch = 1; ch < 256; ++ch ) { - string_ref::size_type pos = sr1.rfind(ch); + string_view::size_type pos = sr1.rfind(ch); const char *strp = std::strrchr ( arg, ch ); - BOOST_CHECK (( strp == NULL ) == ( pos == string_ref::npos )); + BOOST_CHECK (( strp == NULL ) == ( pos == string_view::npos )); if ( strp != NULL ) BOOST_CHECK ( ptr_diff ( strp, arg ) == pos ); } @@ -151,7 +151,7 @@ void find ( const char *arg ) { p = arg; sr1 = arg; while ( !sr1.empty ()) { - string_ref::size_type pos = sr1.find(*p); + string_view::size_type pos = sr1.find(*p); BOOST_CHECK ( pos == 0 ); sr1.remove_prefix (1); ++p; @@ -161,7 +161,7 @@ void find ( const char *arg ) { sr1 = arg; p = arg + std::strlen ( arg ) - 1; while ( !sr1.empty ()) { - string_ref::size_type pos = sr1.rfind(*p); + string_view::size_type pos = sr1.rfind(*p); BOOST_CHECK ( pos == sr1.size () - 1 ); sr1.remove_suffix (1); --p; @@ -171,7 +171,7 @@ void find ( const char *arg ) { sr1 = arg; p = arg; while ( !sr1.empty ()) { - string_ref::size_type pos = sr1.find_first_of(*p); + string_view::size_type pos = sr1.find_first_of(*p); BOOST_CHECK ( pos == 0 ); sr1.remove_prefix (1); ++p; @@ -182,7 +182,7 @@ void find ( const char *arg ) { sr1 = arg; p = arg + std::strlen ( arg ) - 1; while ( !sr1.empty ()) { - string_ref::size_type pos = sr1.find_last_of(*p); + string_view::size_type pos = sr1.find_last_of(*p); BOOST_CHECK ( pos == sr1.size () - 1 ); sr1.remove_suffix (1); --p; @@ -193,17 +193,17 @@ void find ( const char *arg ) { sr2 = arg; while ( !sr1.empty() ) { BOOST_CHECK ( sr1.find_first_of ( sr2 ) == 0 ); - BOOST_CHECK ( sr1.find_first_not_of ( sr2 ) == string_ref::npos ); + BOOST_CHECK ( sr1.find_first_not_of ( sr2 ) == string_view::npos ); sr1.remove_prefix ( 1 ); } p = arg; sr1 = arg; while ( *p ) { - string_ref::size_type pos1 = sr1.find_first_of(*p); - string_ref::size_type pos2 = sr1.find_first_not_of(*p); - BOOST_CHECK ( pos1 != string_ref::npos && pos1 < sr1.size () && pos1 <= ptr_diff ( p, arg )); - if ( pos2 != string_ref::npos ) { + string_view::size_type pos1 = sr1.find_first_of(*p); + string_view::size_type pos2 = sr1.find_first_not_of(*p); + BOOST_CHECK ( pos1 != string_view::npos && pos1 < sr1.size () && pos1 <= ptr_diff ( p, arg )); + if ( pos2 != string_view::npos ) { for ( size_t i = 0 ; i < pos2; ++i ) BOOST_CHECK ( sr1[i] == *p ); BOOST_CHECK ( sr1 [ pos2 ] != *p ); @@ -218,18 +218,18 @@ void find ( const char *arg ) { sr2 = arg; while ( !sr1.empty() ) { BOOST_CHECK ( sr1.find_last_of ( sr2 ) == ( sr1.size () - 1 )); - BOOST_CHECK ( sr1.find_last_not_of ( sr2 ) == string_ref::npos ); + BOOST_CHECK ( sr1.find_last_not_of ( sr2 ) == string_view::npos ); sr1.remove_suffix ( 1 ); } p = arg; sr1 = arg; while ( *p ) { - string_ref::size_type pos1 = sr1.find_last_of(*p); - string_ref::size_type pos2 = sr1.find_last_not_of(*p); - BOOST_CHECK ( pos1 != string_ref::npos && pos1 < sr1.size () && pos1 >= ptr_diff ( p, arg )); - BOOST_CHECK ( pos2 == string_ref::npos || pos1 < sr1.size ()); - if ( pos2 != string_ref::npos ) { + string_view::size_type pos1 = sr1.find_last_of(*p); + string_view::size_type pos2 = sr1.find_last_not_of(*p); + BOOST_CHECK ( pos1 != string_view::npos && pos1 < sr1.size () && pos1 >= ptr_diff ( p, arg )); + BOOST_CHECK ( pos2 == string_view::npos || pos1 < sr1.size ()); + if ( pos2 != string_view::npos ) { for ( size_t i = sr1.size () -1 ; i > pos2; --i ) BOOST_CHECK ( sr1[i] == *p ); BOOST_CHECK ( sr1 [ pos2 ] != *p ); @@ -243,7 +243,7 @@ void find ( const char *arg ) { void to_string ( const char *arg ) { - string_ref sr1; + string_view sr1; std::string str1; std::string str2; @@ -260,17 +260,17 @@ void to_string ( const char *arg ) { } void compare ( const char *arg ) { - string_ref sr1; + string_view sr1; std::string str1; std::string str2 = str1; str1.assign ( arg ); sr1 = arg; - BOOST_CHECK ( sr1 == sr1); // compare string_ref and string_ref - BOOST_CHECK ( sr1 == str1); // compare string and string_ref - BOOST_CHECK ( str1 == sr1 ); // compare string_ref and string - BOOST_CHECK ( sr1 == arg ); // compare string_ref and pointer - BOOST_CHECK ( arg == sr1 ); // compare pointer and string_ref + BOOST_CHECK ( sr1 == sr1); // compare string_view and string_view + BOOST_CHECK ( sr1 == str1); // compare string and string_view + BOOST_CHECK ( str1 == sr1 ); // compare string_view and string + BOOST_CHECK ( sr1 == arg ); // compare string_view and pointer + BOOST_CHECK ( arg == sr1 ); // compare pointer and string_view if ( sr1.size () > 0 ) { (*str1.rbegin())++; diff --git a/test/string_view_test3.cpp b/test/string_view_test3.cpp new file mode 100644 index 0000000..9ac829d --- /dev/null +++ b/test/string_view_test3.cpp @@ -0,0 +1,29 @@ +/* + Copyright (c) Beman Dawes 2015 + + Distributed under the Boost Software License, Version 1.0 + See http://www.boost.org/LICENSE_1_0.txt + + For more information, see http://www.boost.org +*/ + +#include + +#include +#include +#include + +#define BOOST_LIGHTWEIGHT_TEST_OSTREAM std::cout +#include + +namespace +{ + +} // unnamed namespace + +int main() +{ + typedef boost::string_view::traits_type string_traits; + + return boost::report_errors(); +} diff --git a/test/string_view_test_io.cpp b/test/string_view_test_io.cpp index 376f695..e1cb307 100644 --- a/test/string_view_test_io.cpp +++ b/test/string_view_test_io.cpp @@ -5,16 +5,16 @@ * http://www.boost.org/LICENSE_1_0.txt) */ /*! - * \file string_ref_test_io.cpp + * \file string_view_test_io.cpp * \author Andrey Semashev * \date 26.05.2013 * - * \brief This header contains tests for stream operations of \c basic_string_ref. + * \brief This header contains tests for stream operations of \c basic_string_view. */ -#define BOOST_TEST_MODULE string_ref_test_io +#define BOOST_TEST_MODULE string_view_test_io -#include +#include #include #include @@ -60,7 +60,7 @@ struct context context() { - boost::string_ref str = test_strings[0]; + boost::string_view str = test_strings[0]; std::copy(str.begin(), str.end(), std::back_inserter(begin)); str = test_strings[1]; @@ -72,17 +72,17 @@ struct context }; // Test regular output -BOOST_AUTO_TEST_CASE_TEMPLATE(string_ref_output, CharT, char_types) +BOOST_AUTO_TEST_CASE_TEMPLATE(string_view_output, CharT, char_types) { typedef CharT char_type; typedef std::basic_string< char_type > string_type; typedef std::basic_ostringstream< char_type > ostream_type; - typedef boost::basic_string_ref< char_type > string_ref_type; + typedef boost::basic_string_view< char_type > string_view_type; context< char_type > ctx; ostream_type strm; - strm << string_ref_type(ctx.abcd); + strm << string_view_type(ctx.abcd); BOOST_CHECK(strm.str() == ctx.abcd); } @@ -92,41 +92,41 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(padding, CharT, char_types) typedef CharT char_type; typedef std::basic_string< char_type > string_type; typedef std::basic_ostringstream< char_type > ostream_type; - typedef boost::basic_string_ref< char_type > string_ref_type; + typedef boost::basic_string_view< char_type > string_view_type; context< char_type > ctx; // Test for padding { - ostream_type strm_ref; - strm_ref << ctx.begin << std::setw(8) << string_ref_type(ctx.abcd) << ctx.end; + ostream_type strm_view; + strm_view << ctx.begin << std::setw(8) << string_view_type(ctx.abcd) << ctx.end; ostream_type strm_correct; strm_correct << ctx.begin << std::setw(8) << ctx.abcd << ctx.end; - BOOST_CHECK(strm_ref.str() == strm_correct.str()); + BOOST_CHECK(strm_view.str() == strm_correct.str()); } // Test for long padding { - ostream_type strm_ref; - strm_ref << ctx.begin << std::setw(100) << string_ref_type(ctx.abcd) << ctx.end; + ostream_type strm_view; + strm_view << ctx.begin << std::setw(100) << string_view_type(ctx.abcd) << ctx.end; ostream_type strm_correct; strm_correct << ctx.begin << std::setw(100) << ctx.abcd << ctx.end; - BOOST_CHECK(strm_ref.str() == strm_correct.str()); + BOOST_CHECK(strm_view.str() == strm_correct.str()); } // Test that short width does not truncate the string { - ostream_type strm_ref; - strm_ref << ctx.begin << std::setw(1) << string_ref_type(ctx.abcd) << ctx.end; + ostream_type strm_view; + strm_view << ctx.begin << std::setw(1) << string_view_type(ctx.abcd) << ctx.end; ostream_type strm_correct; strm_correct << ctx.begin << std::setw(1) << ctx.abcd << ctx.end; - BOOST_CHECK(strm_ref.str() == strm_correct.str()); + BOOST_CHECK(strm_view.str() == strm_correct.str()); } } @@ -136,17 +136,17 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(padding_fill, CharT, char_types) typedef CharT char_type; typedef std::basic_string< char_type > string_type; typedef std::basic_ostringstream< char_type > ostream_type; - typedef boost::basic_string_ref< char_type > string_ref_type; + typedef boost::basic_string_view< char_type > string_view_type; context< char_type > ctx; - ostream_type strm_ref; - strm_ref << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << string_ref_type(ctx.abcd) << ctx.end; + ostream_type strm_view; + strm_view << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << string_view_type(ctx.abcd) << ctx.end; ostream_type strm_correct; strm_correct << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << ctx.abcd << ctx.end; - BOOST_CHECK(strm_ref.str() == strm_correct.str()); + BOOST_CHECK(strm_view.str() == strm_correct.str()); } // Test support for alignment @@ -155,29 +155,29 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(alignment, CharT, char_types) typedef CharT char_type; typedef std::basic_string< char_type > string_type; typedef std::basic_ostringstream< char_type > ostream_type; - typedef boost::basic_string_ref< char_type > string_ref_type; + typedef boost::basic_string_view< char_type > string_view_type; context< char_type > ctx; // Left alignment { - ostream_type strm_ref; - strm_ref << ctx.begin << std::left << std::setw(8) << string_ref_type(ctx.abcd) << ctx.end; + ostream_type strm_view; + strm_view << ctx.begin << std::left << std::setw(8) << string_view_type(ctx.abcd) << ctx.end; ostream_type strm_correct; strm_correct << ctx.begin << std::left << std::setw(8) << ctx.abcd << ctx.end; - BOOST_CHECK(strm_ref.str() == strm_correct.str()); + BOOST_CHECK(strm_view.str() == strm_correct.str()); } // Right alignment { - ostream_type strm_ref; - strm_ref << ctx.begin << std::right << std::setw(8) << string_ref_type(ctx.abcd) << ctx.end; + ostream_type strm_view; + strm_view << ctx.begin << std::right << std::setw(8) << string_view_type(ctx.abcd) << ctx.end; ostream_type strm_correct; strm_correct << ctx.begin << std::right << std::setw(8) << ctx.abcd << ctx.end; - BOOST_CHECK(strm_ref.str() == strm_correct.str()); + BOOST_CHECK(strm_view.str() == strm_correct.str()); } }