Commit 32f9be16 by Edward Smith-Rowland Committed by Edward Smith-Rowland

string_view: Rep empty string with unit-length static constexpr string.

2013-11-21  Edward Smith-Rowland  <3dw4rd@verizon.net>

	* include/experimental/string_view: Rep empty string with unit-length
	static constexpr string. Uncomment _GLIBCXX_VISIBILITY. Enforce
	invariant of no nullptr string pointer.
	* include/experimental/string_view.tcc: Ditto.
	* testsuite/experimental/string_view/cons/char/1.cc: data() for empty
	string_view is no longer nullptr.
	* testsuite/experimental/string_view/cons/wchar_t/1.cc: Ditto.
	* testsuite/experimental/string_view/operations/data/char/1.cc: Ditto.
	* testsuite/experimental/string_view/operations/data/wchar_t/1.cc:
	Ditto.

From-SVN: r205213
parent d2ae7b11
2013-11-21 Edward Smith-Rowland <3dw4rd@verizon.net> 2013-11-21 Edward Smith-Rowland <3dw4rd@verizon.net>
* include/experimental/string_view: Rep empty string with unit-length
static constexpr string. Uncomment _GLIBCXX_VISIBILITY. Enforce
invariant of no nullptr string pointer.
* include/experimental/string_view.tcc: Ditto.
* testsuite/experimental/string_view/cons/char/1.cc: data() for empty
string_view is no longer nullptr.
* testsuite/experimental/string_view/cons/wchar_t/1.cc: Ditto.
* testsuite/experimental/string_view/operations/data/char/1.cc: Ditto.
* testsuite/experimental/string_view/operations/data/wchar_t/1.cc:
Ditto.
2013-11-21 Edward Smith-Rowland <3dw4rd@verizon.net>
Implement __gnu_cxx::hypergeometric_distribution. Implement __gnu_cxx::hypergeometric_distribution.
* include/ext/random: Add hypergeometric_distribution. * include/ext/random: Add hypergeometric_distribution.
* include/ext/random.tcc: Add hypergeometric_distribution. * include/ext/random.tcc: Add hypergeometric_distribution.
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
#include <string> #include <string>
#include <limits> #include <limits>
namespace std //_GLIBCXX_VISIBILITY(default) namespace std _GLIBCXX_VISIBILITY(default)
{ {
namespace experimental namespace experimental
{ {
...@@ -66,6 +66,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -66,6 +66,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* _CharT* _M_str * _CharT* _M_str
* size_t _M_len * size_t _M_len
* @endcode * @endcode
*
* A basic_string_view represents an empty string with a static constexpr
* length one string:
*
* @code
* static constexpr value_type _S_empty_str[1]{0};
* @endcode
*/ */
template<typename _CharT, typename _Traits = char_traits<_CharT>> template<typename _CharT, typename _Traits = char_traits<_CharT>>
class basic_string_view class basic_string_view
...@@ -92,7 +99,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -92,7 +99,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr constexpr
basic_string_view() noexcept basic_string_view() noexcept
: _M_len{0}, _M_str{nullptr} : _M_len{0}, _M_str{_S_empty_str}
{ } { }
constexpr basic_string_view(const basic_string_view&) noexcept = default; constexpr basic_string_view(const basic_string_view&) noexcept = default;
...@@ -104,11 +111,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -104,11 +111,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ } { }
constexpr basic_string_view(const _CharT* __str) constexpr basic_string_view(const _CharT* __str)
: _M_len{__str == nullptr ? 0 : traits_type::length(__str)}, _M_str{__str} : _M_len{__str == nullptr ? 0 : traits_type::length(__str)},
_M_str{__str == nullptr ? _S_empty_str : __str}
{ } { }
constexpr basic_string_view(const _CharT* __str, size_type __len) constexpr basic_string_view(const _CharT* __str, size_type __len)
: _M_len{__len}, _M_str{__str} : _M_len{__str == nullptr ? 0 :__len},
_M_str{__str == nullptr || __len == 0 ? _S_empty_str : __str}
{ } { }
basic_string_view& basic_string_view&
...@@ -185,7 +194,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -185,7 +194,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
"(which is %zu) >= this->size() " "(which is %zu) >= this->size() "
"(which is %zu)"), "(which is %zu)"),
__pos, this->size()), __pos, this->size()),
*static_cast<pointer>(nullptr)); _S_empty_str[0]);
} }
constexpr const _CharT& constexpr const _CharT&
...@@ -211,7 +220,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -211,7 +220,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
clear() noexcept clear() noexcept
{ {
this->_M_len = 0; this->_M_len = 0;
this->_M_str = nullptr; this->_M_str = _S_empty_str;
} }
void void
...@@ -408,6 +417,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -408,6 +417,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
} }
private: private:
static constexpr const int static constexpr const int
_S_compare(size_type __n1, size_type __n2) noexcept _S_compare(size_type __n1, size_type __n2) noexcept
{ {
...@@ -418,6 +428,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -418,6 +428,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: static_cast<int>(difference_type{__n1 - __n2}); : static_cast<int>(difference_type{__n1 - __n2});
} }
static constexpr value_type _S_empty_str[1]{};
size_t _M_len; size_t _M_len;
const _CharT* _M_str; const _CharT* _M_str;
}; };
......
...@@ -40,13 +40,17 @@ ...@@ -40,13 +40,17 @@
# include <bits/c++14_warning.h> # include <bits/c++14_warning.h>
#else #else
namespace std //_GLIBCXX_VISIBILITY(default) namespace std _GLIBCXX_VISIBILITY(default)
{ {
namespace experimental namespace experimental
{ {
_GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT, typename _Traits> template<typename _CharT, typename _Traits>
constexpr _CharT
basic_string_view<_CharT, _Traits>::_S_empty_str[1];
template<typename _CharT, typename _Traits>
typename basic_string_view<_CharT, _Traits>::size_type typename basic_string_view<_CharT, _Traits>::size_type
basic_string_view<_CharT, _Traits>:: basic_string_view<_CharT, _Traits>::
find(const _CharT* __str, size_type __pos, size_type __n) const noexcept find(const _CharT* __str, size_type __pos, size_type __n) const noexcept
......
...@@ -33,7 +33,7 @@ test01() ...@@ -33,7 +33,7 @@ test01()
// basic_string_view() // basic_string_view()
const std::experimental::string_view str00{}; const std::experimental::string_view str00{};
VERIFY( str00.length() == 0 ); VERIFY( str00.length() == 0 );
VERIFY( str00.data() == nullptr ); VERIFY( str00.data() != nullptr );
// basic_string_view(const char*) // basic_string_view(const char*)
const char str_lit01[] = "rodeo beach, marin"; const char str_lit01[] = "rodeo beach, marin";
...@@ -53,10 +53,11 @@ test01() ...@@ -53,10 +53,11 @@ test01()
std::experimental::string_view str05{str_lit01, len_lit01}; std::experimental::string_view str05{str_lit01, len_lit01};
VERIFY( str05.length() == len_lit01 ); VERIFY( str05.length() == len_lit01 );
VERIFY( str05.data() == str_lit01 ); VERIFY( str05.data() == str_lit01 );
// This is invalid and unchecked.
//std::experimental::string_view str06{nullptr, len_lit01}; // basic_string_view(const char* s, std::size_t l)
//VERIFY( str06.length() == 0 ); std::experimental::string_view str06{nullptr, len_lit01};
//VERIFY( str06.data() == nullptr ); VERIFY( str06.length() == 0 );
VERIFY( str06.data() != nullptr );
// basic_string_view(basic_string& s) // basic_string_view(basic_string& s)
std::string istr07(10, 'z'); std::string istr07(10, 'z');
......
...@@ -33,7 +33,7 @@ test01() ...@@ -33,7 +33,7 @@ test01()
// basic_string_view() // basic_string_view()
const std::experimental::wstring_view str00{}; const std::experimental::wstring_view str00{};
VERIFY( str00.length() == 0 ); VERIFY( str00.length() == 0 );
VERIFY( str00.data() == nullptr ); VERIFY( str00.data() != nullptr );
// basic_string_view(const char*) // basic_string_view(const char*)
const wchar_t str_lit01[] = L"rodeo beach, marin"; const wchar_t str_lit01[] = L"rodeo beach, marin";
...@@ -53,10 +53,11 @@ test01() ...@@ -53,10 +53,11 @@ test01()
std::experimental::wstring_view str05{str_lit01, len_lit01}; std::experimental::wstring_view str05{str_lit01, len_lit01};
VERIFY( str05.length() == len_lit01 ); VERIFY( str05.length() == len_lit01 );
VERIFY( str05.data() == str_lit01 ); VERIFY( str05.data() == str_lit01 );
// This is invalid and unchecked.
//std::experimental::wstring_view str06{nullptr, len_lit01}; // basic_string_view(const wchar_t* s, std::size_t l)
//VERIFY( str06.length() == 0 ); std::experimental::wstring_view str06{nullptr, len_lit01};
//VERIFY( str06.data() == nullptr ); VERIFY( str06.length() == 0 );
VERIFY( str06.data() != nullptr );
// basic_string_view(basic_string& s) // basic_string_view(basic_string& s)
std::wstring istr07(10, L'z'); std::wstring istr07(10, L'z');
......
...@@ -29,10 +29,10 @@ test01() ...@@ -29,10 +29,10 @@ test01()
std::experimental::string_view empty; std::experimental::string_view empty;
// data() for size == 0 is non-NULL? // data() for size == 0 is non-NULL.
VERIFY( empty.size() == 0 ); VERIFY( empty.size() == 0 );
const std::experimental::string_view::value_type* p = empty.data(); const std::experimental::string_view::value_type* p = empty.data();
VERIFY( p == nullptr ); VERIFY( p );
return 0; return 0;
} }
......
...@@ -29,10 +29,10 @@ test01() ...@@ -29,10 +29,10 @@ test01()
std::experimental::wstring_view empty; std::experimental::wstring_view empty;
// data() for size == 0 is non-NULL? // data() for size == 0 is non-NULL.
VERIFY( empty.size() == 0 ); VERIFY( empty.size() == 0 );
const std::experimental::wstring_view::value_type* p = empty.data(); const std::experimental::wstring_view::value_type* p = empty.data();
VERIFY( p == nullptr ); VERIFY( p );
return 0; return 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment