diff --git a/include/boost/utility/string_ref.hpp b/include/boost/utility/string_ref.hpp index 6d5cace..1bab84c 100644 --- a/include/boost/utility/string_ref.hpp +++ b/include/boost/utility/string_ref.hpp @@ -17,10 +17,13 @@ #include #include +#include +#include +#include #include #include -#include +#include #include namespace boost { @@ -36,18 +39,6 @@ namespace boost { }; } - template class basic_string_ref; - typedef basic_string_ref > string_ref; - typedef basic_string_ref > wstring_ref; - -#ifndef BOOST_NO_CXX11_CHAR16_T - typedef basic_string_ref > u16string_ref; -#endif - -#ifndef BOOST_NO_CXX11_CHAR32_T - typedef basic_string_ref > u32string_ref; -#endif - template class basic_string_ref { public: @@ -61,7 +52,7 @@ namespace boost { typedef std::reverse_iterator const_reverse_iterator; typedef const_reverse_iterator reverse_iterator; 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); // construct/copy @@ -119,7 +110,7 @@ namespace boost { const charT& at(size_t pos) const { 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]; } @@ -146,16 +137,13 @@ namespace boost { // basic_string_ref string operations BOOST_CONSTEXPR 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 // a conditional operator is a throw expression. -EAN 2012/12/04 - if ( pos > size()) throw std::out_of_range ( "string_ref::substr" ); - if ( n == npos || pos + n > size()) n = size () - pos; + if ( pos > size()) + 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 ); -#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 { @@ -260,173 +248,190 @@ namespace boost { // Comparison operators // Equality template - bool operator==(basic_string_ref x, basic_string_ref y) { + inline bool operator==(basic_string_ref x, basic_string_ref y) { if ( x.size () != y.size ()) return false; return x.compare(y) == 0; } template - bool operator==(basic_string_ref x, const std::basic_string & y) { + inline bool operator==(basic_string_ref x, const std::basic_string & y) { return x == basic_string_ref(y); } template - bool operator==(const std::basic_string & x, basic_string_ref y) { + inline bool operator==(const std::basic_string & x, basic_string_ref y) { return basic_string_ref(x) == y; } template - bool operator==(basic_string_ref x, const charT * y) { + inline bool operator==(basic_string_ref x, const charT * y) { return x == basic_string_ref(y); } template - bool operator==(const charT * x, basic_string_ref y) { + inline bool operator==(const charT * x, basic_string_ref y) { return basic_string_ref(x) == y; } // Inequality template - bool operator!=(basic_string_ref x, basic_string_ref y) { + inline bool operator!=(basic_string_ref x, basic_string_ref y) { if ( x.size () != y.size ()) return true; return x.compare(y) != 0; } template - bool operator!=(basic_string_ref x, const std::basic_string & y) { + inline bool operator!=(basic_string_ref x, const std::basic_string & y) { return x != basic_string_ref(y); } template - bool operator!=(const std::basic_string & x, basic_string_ref y) { + inline bool operator!=(const std::basic_string & x, basic_string_ref y) { return basic_string_ref(x) != y; } template - bool operator!=(basic_string_ref x, const charT * y) { + inline bool operator!=(basic_string_ref x, const charT * y) { return x != basic_string_ref(y); } template - bool operator!=(const charT * x, basic_string_ref y) { + inline bool operator!=(const charT * x, basic_string_ref y) { return basic_string_ref(x) != y; } // Less than template - bool operator<(basic_string_ref x, basic_string_ref y) { + inline bool operator<(basic_string_ref x, basic_string_ref y) { return x.compare(y) < 0; } template - bool operator<(basic_string_ref x, const std::basic_string & y) { + inline bool operator<(basic_string_ref x, const std::basic_string & y) { return x < basic_string_ref(y); } template - bool operator<(const std::basic_string & x, basic_string_ref y) { + inline bool operator<(const std::basic_string & x, basic_string_ref y) { return basic_string_ref(x) < y; } template - bool operator<(basic_string_ref x, const charT * y) { + inline bool operator<(basic_string_ref x, const charT * y) { return x < basic_string_ref(y); } template - bool operator<(const charT * x, basic_string_ref y) { + inline bool operator<(const charT * x, basic_string_ref y) { return basic_string_ref(x) < y; } // Greater than template - bool operator>(basic_string_ref x, basic_string_ref y) { + inline bool operator>(basic_string_ref x, basic_string_ref y) { return x.compare(y) > 0; } template - bool operator>(basic_string_ref x, const std::basic_string & y) { + inline bool operator>(basic_string_ref x, const std::basic_string & y) { return x > basic_string_ref(y); } template - bool operator>(const std::basic_string & x, basic_string_ref y) { + inline bool operator>(const std::basic_string & x, basic_string_ref y) { return basic_string_ref(x) > y; } template - bool operator>(basic_string_ref x, const charT * y) { + inline bool operator>(basic_string_ref x, const charT * y) { return x > basic_string_ref(y); } template - bool operator>(const charT * x, basic_string_ref y) { + inline bool operator>(const charT * x, basic_string_ref y) { return basic_string_ref(x) > y; } // Less than or equal to template - bool operator<=(basic_string_ref x, basic_string_ref y) { + inline bool operator<=(basic_string_ref x, basic_string_ref y) { return x.compare(y) <= 0; } template - bool operator<=(basic_string_ref x, const std::basic_string & y) { + inline bool operator<=(basic_string_ref x, const std::basic_string & y) { return x <= basic_string_ref(y); } template - bool operator<=(const std::basic_string & x, basic_string_ref y) { + inline bool operator<=(const std::basic_string & x, basic_string_ref y) { return basic_string_ref(x) <= y; } template - bool operator<=(basic_string_ref x, const charT * y) { + inline bool operator<=(basic_string_ref x, const charT * y) { return x <= basic_string_ref(y); } template - bool operator<=(const charT * x, basic_string_ref y) { + inline bool operator<=(const charT * x, basic_string_ref y) { return basic_string_ref(x) <= y; } // Greater than or equal to template - bool operator>=(basic_string_ref x, basic_string_ref y) { + inline bool operator>=(basic_string_ref x, basic_string_ref y) { return x.compare(y) >= 0; } template - bool operator>=(basic_string_ref x, const std::basic_string & y) { + inline bool operator>=(basic_string_ref x, const std::basic_string & y) { return x >= basic_string_ref(y); } template - bool operator>=(const std::basic_string & x, basic_string_ref y) { + inline bool operator>=(const std::basic_string & x, basic_string_ref y) { return basic_string_ref(x) >= y; } template - bool operator>=(basic_string_ref x, const charT * y) { + inline bool operator>=(basic_string_ref x, const charT * y) { return x >= basic_string_ref(y); } template - bool operator>=(const charT * x, basic_string_ref y) { + inline bool operator>=(const charT * x, basic_string_ref y) { return basic_string_ref(x) >= y; } // Inserter template - std::basic_ostream& + inline std::basic_ostream& operator<<(std::basic_ostream& os, const basic_string_ref& str) { -#ifdef BOOST_NO_CXX11_RANGE_BASED_FOR - for ( typename basic_string_ref::const_iterator iter = str.begin (); iter != str.end (); ++iter ) - os << *iter; -#else - for ( charT x : str ) - os << x; -#endif + typename std::basic_ostream::sentry guard(os); + if (guard) { + const std::size_t size = str.size(); + const std::size_t w = static_cast< std::size_t >(os.width()); + os.width(0); + if (w <= size) + os.write(str.data(), size); + else { + const bool align_left = (os.flags() & std::basic_ostream::adjustfield) == std::basic_ostream::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; } @@ -436,67 +441,67 @@ namespace boost { // These are short-term implementations. // 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 ); } - 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 ); } - 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 ); } - 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 ); } - 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 ); } - 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 ); } - 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 ); } - 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 ); } - 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 ); } - 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 ); } - 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 ); } - 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 ); } - 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 ); } - 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 ); } - 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 ); } - 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 ); } #endif diff --git a/include/boost/utility/string_ref_fwd.hpp b/include/boost/utility/string_ref_fwd.hpp new file mode 100644 index 0000000..f58b98c --- /dev/null +++ b/include/boost/utility/string_ref_fwd.hpp @@ -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 +#include + +namespace boost { + + template > class basic_string_ref; + typedef basic_string_ref > string_ref; + typedef basic_string_ref > wstring_ref; + +#ifndef BOOST_NO_CXX11_CHAR16_T + typedef basic_string_ref > u16string_ref; +#endif + +#ifndef BOOST_NO_CXX11_CHAR32_T + typedef basic_string_ref > u32string_ref; +#endif + +} + +#endif