1. Extracted forward declarations to a separate header so that it can be included by other libraries (Boost.Log, for instance).

2. Added a default value for char traits template parameter.
3. Added missing headers and removed unused ones.
4. Added inline specifiers to operators.
5. Fixed operator<< behaving incorrectly when particular width is requested (std::setw, etc.).
6. Replaced all throw statements with BOOST_THROW_EXCEPTION.


[SVN r84511]
This commit is contained in:
Andrey Semashev 2013-05-26 15:36:25 +00:00
parent 1057ff4d9e
commit 91aab126e1
2 changed files with 118 additions and 76 deletions

View File

@ -17,10 +17,13 @@
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/detail/workaround.hpp> #include <boost/detail/workaround.hpp>
#include <boost/utility/string_ref_fwd.hpp>
#include <boost/throw_exception.hpp>
#include <cstddef>
#include <stdexcept> #include <stdexcept>
#include <algorithm> #include <algorithm>
#include <functional> #include <iterator>
#include <string> #include <string>
namespace boost { namespace boost {
@ -36,18 +39,6 @@ namespace boost {
}; };
} }
template<typename charT, typename traits> class basic_string_ref;
typedef basic_string_ref<char, std::char_traits<char> > string_ref;
typedef basic_string_ref<wchar_t, std::char_traits<wchar_t> > wstring_ref;
#ifndef BOOST_NO_CXX11_CHAR16_T
typedef basic_string_ref<char16_t, std::char_traits<char16_t> > u16string_ref;
#endif
#ifndef BOOST_NO_CXX11_CHAR32_T
typedef basic_string_ref<char32_t, std::char_traits<char32_t> > u32string_ref;
#endif
template<typename charT, typename traits> template<typename charT, typename traits>
class basic_string_ref { class basic_string_ref {
public: public:
@ -61,7 +52,7 @@ namespace boost {
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef const_reverse_iterator reverse_iterator; typedef const_reverse_iterator reverse_iterator;
typedef std::size_t size_type; typedef std::size_t size_type;
typedef ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
static BOOST_CONSTEXPR_OR_CONST size_type npos = size_type(-1); static BOOST_CONSTEXPR_OR_CONST size_type npos = size_type(-1);
// construct/copy // construct/copy
@ -119,7 +110,7 @@ namespace boost {
const charT& at(size_t pos) const { const charT& at(size_t pos) const {
if ( pos >= len_ ) if ( pos >= len_ )
throw std::out_of_range ( "boost::string_ref::at" ); BOOST_THROW_EXCEPTION( std::out_of_range ( "boost::string_ref::at" ) );
return ptr_[pos]; return ptr_[pos];
} }
@ -146,16 +137,13 @@ namespace boost {
// basic_string_ref string operations // basic_string_ref string operations
BOOST_CONSTEXPR BOOST_CONSTEXPR
basic_string_ref substr(size_type pos, size_type n=npos) const { basic_string_ref substr(size_type pos, size_type n=npos) const {
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1600)
// Looks like msvc 8 and 9 have a codegen bug when one branch of // Looks like msvc 8 and 9 have a codegen bug when one branch of
// a conditional operator is a throw expression. -EAN 2012/12/04 // a conditional operator is a throw expression. -EAN 2012/12/04
if ( pos > size()) throw std::out_of_range ( "string_ref::substr" ); if ( pos > size())
if ( n == npos || pos + n > size()) n = size () - pos; BOOST_THROW_EXCEPTION( std::out_of_range ( "string_ref::substr" ) );
if ( n == npos || pos + n > size())
n = size () - pos;
return basic_string_ref ( data() + pos, n ); return basic_string_ref ( data() + pos, n );
#else
return pos > size() ? throw std::out_of_range ( "string_ref::substr" ) :
basic_string_ref ( data() + pos, n == npos || pos + n > size() ? size() - pos : n );
#endif
} }
int compare(basic_string_ref x) const { int compare(basic_string_ref x) const {
@ -260,173 +248,190 @@ namespace boost {
// Comparison operators // Comparison operators
// Equality // Equality
template<typename charT, typename traits> template<typename charT, typename traits>
bool operator==(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) { inline bool operator==(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
if ( x.size () != y.size ()) return false; if ( x.size () != y.size ()) return false;
return x.compare(y) == 0; return x.compare(y) == 0;
} }
template<typename charT, typename traits, typename Allocator> template<typename charT, typename traits, typename Allocator>
bool operator==(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) { inline bool operator==(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
return x == basic_string_ref<charT, traits>(y); return x == basic_string_ref<charT, traits>(y);
} }
template<typename charT, typename traits, typename Allocator> template<typename charT, typename traits, typename Allocator>
bool operator==(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) { inline bool operator==(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) == y; return basic_string_ref<charT, traits>(x) == y;
} }
template<typename charT, typename traits> template<typename charT, typename traits>
bool operator==(basic_string_ref<charT, traits> x, const charT * y) { inline bool operator==(basic_string_ref<charT, traits> x, const charT * y) {
return x == basic_string_ref<charT, traits>(y); return x == basic_string_ref<charT, traits>(y);
} }
template<typename charT, typename traits> template<typename charT, typename traits>
bool operator==(const charT * x, basic_string_ref<charT, traits> y) { inline bool operator==(const charT * x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) == y; return basic_string_ref<charT, traits>(x) == y;
} }
// Inequality // Inequality
template<typename charT, typename traits> template<typename charT, typename traits>
bool operator!=(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) { inline bool operator!=(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
if ( x.size () != y.size ()) return true; if ( x.size () != y.size ()) return true;
return x.compare(y) != 0; return x.compare(y) != 0;
} }
template<typename charT, typename traits, typename Allocator> template<typename charT, typename traits, typename Allocator>
bool operator!=(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) { inline bool operator!=(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
return x != basic_string_ref<charT, traits>(y); return x != basic_string_ref<charT, traits>(y);
} }
template<typename charT, typename traits, typename Allocator> template<typename charT, typename traits, typename Allocator>
bool operator!=(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) { inline bool operator!=(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) != y; return basic_string_ref<charT, traits>(x) != y;
} }
template<typename charT, typename traits> template<typename charT, typename traits>
bool operator!=(basic_string_ref<charT, traits> x, const charT * y) { inline bool operator!=(basic_string_ref<charT, traits> x, const charT * y) {
return x != basic_string_ref<charT, traits>(y); return x != basic_string_ref<charT, traits>(y);
} }
template<typename charT, typename traits> template<typename charT, typename traits>
bool operator!=(const charT * x, basic_string_ref<charT, traits> y) { inline bool operator!=(const charT * x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) != y; return basic_string_ref<charT, traits>(x) != y;
} }
// Less than // Less than
template<typename charT, typename traits> template<typename charT, typename traits>
bool operator<(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) { inline bool operator<(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
return x.compare(y) < 0; return x.compare(y) < 0;
} }
template<typename charT, typename traits, typename Allocator> template<typename charT, typename traits, typename Allocator>
bool operator<(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) { inline bool operator<(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
return x < basic_string_ref<charT, traits>(y); return x < basic_string_ref<charT, traits>(y);
} }
template<typename charT, typename traits, typename Allocator> template<typename charT, typename traits, typename Allocator>
bool operator<(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) { inline bool operator<(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) < y; return basic_string_ref<charT, traits>(x) < y;
} }
template<typename charT, typename traits> template<typename charT, typename traits>
bool operator<(basic_string_ref<charT, traits> x, const charT * y) { inline bool operator<(basic_string_ref<charT, traits> x, const charT * y) {
return x < basic_string_ref<charT, traits>(y); return x < basic_string_ref<charT, traits>(y);
} }
template<typename charT, typename traits> template<typename charT, typename traits>
bool operator<(const charT * x, basic_string_ref<charT, traits> y) { inline bool operator<(const charT * x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) < y; return basic_string_ref<charT, traits>(x) < y;
} }
// Greater than // Greater than
template<typename charT, typename traits> template<typename charT, typename traits>
bool operator>(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) { inline bool operator>(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
return x.compare(y) > 0; return x.compare(y) > 0;
} }
template<typename charT, typename traits, typename Allocator> template<typename charT, typename traits, typename Allocator>
bool operator>(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) { inline bool operator>(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
return x > basic_string_ref<charT, traits>(y); return x > basic_string_ref<charT, traits>(y);
} }
template<typename charT, typename traits, typename Allocator> template<typename charT, typename traits, typename Allocator>
bool operator>(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) { inline bool operator>(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) > y; return basic_string_ref<charT, traits>(x) > y;
} }
template<typename charT, typename traits> template<typename charT, typename traits>
bool operator>(basic_string_ref<charT, traits> x, const charT * y) { inline bool operator>(basic_string_ref<charT, traits> x, const charT * y) {
return x > basic_string_ref<charT, traits>(y); return x > basic_string_ref<charT, traits>(y);
} }
template<typename charT, typename traits> template<typename charT, typename traits>
bool operator>(const charT * x, basic_string_ref<charT, traits> y) { inline bool operator>(const charT * x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) > y; return basic_string_ref<charT, traits>(x) > y;
} }
// Less than or equal to // Less than or equal to
template<typename charT, typename traits> template<typename charT, typename traits>
bool operator<=(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) { inline bool operator<=(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
return x.compare(y) <= 0; return x.compare(y) <= 0;
} }
template<typename charT, typename traits, typename Allocator> template<typename charT, typename traits, typename Allocator>
bool operator<=(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) { inline bool operator<=(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
return x <= basic_string_ref<charT, traits>(y); return x <= basic_string_ref<charT, traits>(y);
} }
template<typename charT, typename traits, typename Allocator> template<typename charT, typename traits, typename Allocator>
bool operator<=(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) { inline bool operator<=(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) <= y; return basic_string_ref<charT, traits>(x) <= y;
} }
template<typename charT, typename traits> template<typename charT, typename traits>
bool operator<=(basic_string_ref<charT, traits> x, const charT * y) { inline bool operator<=(basic_string_ref<charT, traits> x, const charT * y) {
return x <= basic_string_ref<charT, traits>(y); return x <= basic_string_ref<charT, traits>(y);
} }
template<typename charT, typename traits> template<typename charT, typename traits>
bool operator<=(const charT * x, basic_string_ref<charT, traits> y) { inline bool operator<=(const charT * x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) <= y; return basic_string_ref<charT, traits>(x) <= y;
} }
// Greater than or equal to // Greater than or equal to
template<typename charT, typename traits> template<typename charT, typename traits>
bool operator>=(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) { inline bool operator>=(basic_string_ref<charT, traits> x, basic_string_ref<charT, traits> y) {
return x.compare(y) >= 0; return x.compare(y) >= 0;
} }
template<typename charT, typename traits, typename Allocator> template<typename charT, typename traits, typename Allocator>
bool operator>=(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) { inline bool operator>=(basic_string_ref<charT, traits> x, const std::basic_string<charT, traits, Allocator> & y) {
return x >= basic_string_ref<charT, traits>(y); return x >= basic_string_ref<charT, traits>(y);
} }
template<typename charT, typename traits, typename Allocator> template<typename charT, typename traits, typename Allocator>
bool operator>=(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) { inline bool operator>=(const std::basic_string<charT, traits, Allocator> & x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) >= y; return basic_string_ref<charT, traits>(x) >= y;
} }
template<typename charT, typename traits> template<typename charT, typename traits>
bool operator>=(basic_string_ref<charT, traits> x, const charT * y) { inline bool operator>=(basic_string_ref<charT, traits> x, const charT * y) {
return x >= basic_string_ref<charT, traits>(y); return x >= basic_string_ref<charT, traits>(y);
} }
template<typename charT, typename traits> template<typename charT, typename traits>
bool operator>=(const charT * x, basic_string_ref<charT, traits> y) { inline bool operator>=(const charT * x, basic_string_ref<charT, traits> y) {
return basic_string_ref<charT, traits>(x) >= y; return basic_string_ref<charT, traits>(x) >= y;
} }
// Inserter // Inserter
template<class charT, class traits> template<class charT, class traits>
std::basic_ostream<charT, traits>& inline std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& os, const basic_string_ref<charT,traits>& str) { operator<<(std::basic_ostream<charT, traits>& os, const basic_string_ref<charT,traits>& str) {
#ifdef BOOST_NO_CXX11_RANGE_BASED_FOR typename std::basic_ostream<charT, traits>::sentry guard(os);
for ( typename basic_string_ref<charT, traits>::const_iterator iter = str.begin (); iter != str.end (); ++iter ) if (guard) {
os << *iter; const std::size_t size = str.size();
#else const std::size_t w = static_cast< std::size_t >(os.width());
for ( charT x : str ) os.width(0);
os << x; if (w <= size)
#endif os.write(str.data(), size);
else {
const bool align_left = (os.flags() & std::basic_ostream<charT, traits>::adjustfield) == std::basic_ostream<charT, traits>::left;
const std::size_t alignment_size = w - size;
if (!align_left) {
const charT fill_char = os.fill();
for (std::size_t i = 0; i < alignment_size && os.good(); ++i)
os.put(fill_char);
}
if (os.good())
os.write(str.data(), size);
if (align_left && os.good()) {
const charT fill_char = os.fill();
for (std::size_t i = 0; i < alignment_size && os.good(); ++i)
os.put(fill_char);
}
}
}
return os; return os;
} }
@ -436,67 +441,67 @@ namespace boost {
// These are short-term implementations. // These are short-term implementations.
// In a production environment, I would rather avoid the copying. // In a production environment, I would rather avoid the copying.
// //
int stoi (string_ref str, size_t* idx=0, int base=10) { inline int stoi (string_ref str, size_t* idx=0, int base=10) {
return std::stoi ( std::string(str), idx, base ); return std::stoi ( std::string(str), idx, base );
} }
long stol (string_ref str, size_t* idx=0, int base=10) { inline long stol (string_ref str, size_t* idx=0, int base=10) {
return std::stol ( std::string(str), idx, base ); return std::stol ( std::string(str), idx, base );
} }
unsigned long stoul (string_ref str, size_t* idx=0, int base=10) { inline unsigned long stoul (string_ref str, size_t* idx=0, int base=10) {
return std::stoul ( std::string(str), idx, base ); return std::stoul ( std::string(str), idx, base );
} }
long long stoll (string_ref str, size_t* idx=0, int base=10) { inline long long stoll (string_ref str, size_t* idx=0, int base=10) {
return std::stoll ( std::string(str), idx, base ); return std::stoll ( std::string(str), idx, base );
} }
unsigned long long stoull (string_ref str, size_t* idx=0, int base=10) { inline unsigned long long stoull (string_ref str, size_t* idx=0, int base=10) {
return std::stoull ( std::string(str), idx, base ); return std::stoull ( std::string(str), idx, base );
} }
float stof (string_ref str, size_t* idx=0) { inline float stof (string_ref str, size_t* idx=0) {
return std::stof ( std::string(str), idx ); return std::stof ( std::string(str), idx );
} }
double stod (string_ref str, size_t* idx=0) { inline double stod (string_ref str, size_t* idx=0) {
return std::stod ( std::string(str), idx ); return std::stod ( std::string(str), idx );
} }
long double stold (string_ref str, size_t* idx=0) { inline long double stold (string_ref str, size_t* idx=0) {
return std::stold ( std::string(str), idx ); return std::stold ( std::string(str), idx );
} }
int stoi (wstring_ref str, size_t* idx=0, int base=10) { inline int stoi (wstring_ref str, size_t* idx=0, int base=10) {
return std::stoi ( std::wstring(str), idx, base ); return std::stoi ( std::wstring(str), idx, base );
} }
long stol (wstring_ref str, size_t* idx=0, int base=10) { inline long stol (wstring_ref str, size_t* idx=0, int base=10) {
return std::stol ( std::wstring(str), idx, base ); return std::stol ( std::wstring(str), idx, base );
} }
unsigned long stoul (wstring_ref str, size_t* idx=0, int base=10) { inline unsigned long stoul (wstring_ref str, size_t* idx=0, int base=10) {
return std::stoul ( std::wstring(str), idx, base ); return std::stoul ( std::wstring(str), idx, base );
} }
long long stoll (wstring_ref str, size_t* idx=0, int base=10) { inline long long stoll (wstring_ref str, size_t* idx=0, int base=10) {
return std::stoll ( std::wstring(str), idx, base ); return std::stoll ( std::wstring(str), idx, base );
} }
unsigned long long stoull (wstring_ref str, size_t* idx=0, int base=10) { inline unsigned long long stoull (wstring_ref str, size_t* idx=0, int base=10) {
return std::stoull ( std::wstring(str), idx, base ); return std::stoull ( std::wstring(str), idx, base );
} }
float stof (wstring_ref str, size_t* idx=0) { inline float stof (wstring_ref str, size_t* idx=0) {
return std::stof ( std::wstring(str), idx ); return std::stof ( std::wstring(str), idx );
} }
double stod (wstring_ref str, size_t* idx=0) { inline double stod (wstring_ref str, size_t* idx=0) {
return std::stod ( std::wstring(str), idx ); return std::stod ( std::wstring(str), idx );
} }
long double stold (wstring_ref str, size_t* idx=0) { inline long double stold (wstring_ref str, size_t* idx=0) {
return std::stold ( std::wstring(str), idx ); return std::stold ( std::wstring(str), idx );
} }
#endif #endif

View File

@ -0,0 +1,37 @@
/*
Copyright (c) Marshall Clow 2012-2012.
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)
For more information, see http://www.boost.org
Based on the StringRef implementation in LLVM (http://llvm.org) and
N3422 by Jeffrey Yasskin
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3442.html
*/
#ifndef BOOST_STRING_REF_FWD_HPP
#define BOOST_STRING_REF_FWD_HPP
#include <boost/config.hpp>
#include <string>
namespace boost {
template<typename charT, typename traits = std::char_traits<charT> > class basic_string_ref;
typedef basic_string_ref<char, std::char_traits<char> > string_ref;
typedef basic_string_ref<wchar_t, std::char_traits<wchar_t> > wstring_ref;
#ifndef BOOST_NO_CXX11_CHAR16_T
typedef basic_string_ref<char16_t, std::char_traits<char16_t> > u16string_ref;
#endif
#ifndef BOOST_NO_CXX11_CHAR32_T
typedef basic_string_ref<char32_t, std::char_traits<char32_t> > u32string_ref;
#endif
}
#endif