support for C++14 constexpr: basic_string

This commit is contained in:
bolero-MURAKAMI 2013-10-26 14:12:09 +09:00
parent c40b33067e
commit f1c0774f7a
2 changed files with 57 additions and 52 deletions

View file

@ -17,6 +17,9 @@
#include <sprout/iterator/ptr_index_iterator.hpp> #include <sprout/iterator/ptr_index_iterator.hpp>
#include <sprout/algorithm/find_if.hpp> #include <sprout/algorithm/find_if.hpp>
#include <sprout/algorithm/tristate_lexicographical_compare.hpp> #include <sprout/algorithm/tristate_lexicographical_compare.hpp>
#include <sprout/algorithm/copy.hpp>
#include <sprout/algorithm/copy_backward.hpp>
#include <sprout/algorithm/fill.hpp>
#include <sprout/iterator/operation.hpp> #include <sprout/iterator/operation.hpp>
#include <sprout/cstring/strlen.hpp> #include <sprout/cstring/strlen.hpp>
@ -71,8 +74,8 @@ namespace sprout {
; ;
} }
public: public:
static void assign(char_type& c1, char_type const& c2) SPROUT_NOEXCEPT { static SPROUT_CXX14_CONSTEXPR void assign(char_type& c1, char_type const& c2) SPROUT_NOEXCEPT {
impl_type::assign(c1, c2); c1 = c2;
} }
#ifdef SPROUT_NO_CXX11_CHAR_TRAITS #ifdef SPROUT_NO_CXX11_CHAR_TRAITS
static SPROUT_CONSTEXPR bool eq(char_type c1, char_type c2) SPROUT_NOEXCEPT { static SPROUT_CONSTEXPR bool eq(char_type c1, char_type c2) SPROUT_NOEXCEPT {
@ -110,14 +113,17 @@ namespace sprout {
s + n s + n
); );
} }
static char_type* move(char_type* s1, char_type const* s2, std::size_t n) { static SPROUT_CXX14_CONSTEXPR char_type* move(char_type* s1, char_type const* s2, std::size_t n) {
return impl_type::move(s1, s2, n); sprout::copy_backward(s2, s2 + n, s1);
return s1;
} }
static char_type* copy(char_type* s1, char_type const* s2, std::size_t n) { static SPROUT_CXX14_CONSTEXPR char_type* copy(char_type* s1, char_type const* s2, std::size_t n) {
return impl_type::copy(s1, s2, n); sprout::copy(s2, s2 + n, s1);
return s1;
} }
static char_type* assign(char_type* s, std::size_t n, char_type a) { static SPROUT_CXX14_CONSTEXPR char_type* assign(char_type* s, std::size_t n, char_type a) {
return impl_type::assign(s, n, a); sprout::fill(s, s + n, a);
return s;
} }
#ifdef SPROUT_NO_CXX11_CHAR_TRAITS #ifdef SPROUT_NO_CXX11_CHAR_TRAITS
static SPROUT_CONSTEXPR int_type not_eof(int_type c) SPROUT_NOEXCEPT { static SPROUT_CONSTEXPR int_type not_eof(int_type c) SPROUT_NOEXCEPT {
@ -193,18 +199,18 @@ namespace sprout {
); );
} }
template<typename OutputIterator, typename ConstInputIterator> template<typename OutputIterator, typename ConstInputIterator>
static OutputIterator move(OutputIterator s1, ConstInputIterator s2, std::size_t n) { static SPROUT_CXX14_CONSTEXPR OutputIterator move(OutputIterator s1, ConstInputIterator s2, std::size_t n) {
std::copy_backward(s2, s2 + n, s1); sprout::copy_backward(s2, s2 + n, s1);
return s1; return s1;
} }
template<typename OutputIterator, typename ConstInputIterator> template<typename OutputIterator, typename ConstInputIterator>
static OutputIterator copy(OutputIterator s1, ConstInputIterator s2, std::size_t n) { static SPROUT_CXX14_CONSTEXPR OutputIterator copy(OutputIterator s1, ConstInputIterator s2, std::size_t n) {
std::copy(s2, s2 + n, s1); sprout::copy(s2, s2 + n, s1);
return s1; return s1;
} }
template<typename OutputIterator> template<typename OutputIterator>
static OutputIterator assign(OutputIterator s, std::size_t n, char_type a) { static SPROUT_CXX14_CONSTEXPR OutputIterator assign(OutputIterator s, std::size_t n, char_type a) {
std::fill(s, s + n, a); sprout::fill(s, s + n, a);
return s; return s;
} }
#endif #endif

View file

@ -25,6 +25,7 @@
#include <sprout/iterator/operation.hpp> #include <sprout/iterator/operation.hpp>
#include <sprout/iterator/type_traits/is_iterator_of.hpp> #include <sprout/iterator/type_traits/is_iterator_of.hpp>
#include <sprout/algorithm/find.hpp> #include <sprout/algorithm/find.hpp>
#include <sprout/algorithm/swap_ranges.hpp>
#include <sprout/utility/forward.hpp> #include <sprout/utility/forward.hpp>
#include <sprout/utility/swap.hpp> #include <sprout/utility/swap.hpp>
#include <sprout/type_traits/identity.hpp> #include <sprout/type_traits/identity.hpp>
@ -281,14 +282,12 @@ namespace sprout {
sprout::detail::string_raw_construct_t(), n, sprout::forward<Args>(args)... sprout::detail::string_raw_construct_t(), n, sprout::forward<Args>(args)...
) )
{} {}
void SPROUT_CXX14_CONSTEXPR void maxcheck(size_type n) const {
maxcheck(size_type n) const {
if (n > static_size) { if (n > static_size) {
throw std::out_of_range("basic_string<>: index out of range"); throw std::out_of_range("basic_string<>: index out of range");
} }
} }
void SPROUT_CXX14_CONSTEXPR void lengthcheck(size_type n) const {
lengthcheck(size_type n) const {
if (n > static_size) { if (n > static_size) {
throw std::length_error("basic_string<>: length error"); throw std::length_error("basic_string<>: length error");
} }
@ -371,26 +370,26 @@ namespace sprout {
) )
{} {}
basic_string& SPROUT_CXX14_CONSTEXPR basic_string&
operator=(basic_string const& rhs) { operator=(basic_string const& rhs) {
return assign(rhs); return assign(rhs);
} }
template<std::size_t N2, typename Enable = typename std::enable_if<(N2 != N)>::type> template<std::size_t N2, typename Enable = typename std::enable_if<(N2 != N)>::type>
basic_string& SPROUT_CXX14_CONSTEXPR basic_string&
operator=(basic_string<T, N2, Traits> const& rhs) { operator=(basic_string<T, N2, Traits> const& rhs) {
return assign(rhs); return assign(rhs);
} }
basic_string& SPROUT_CXX14_CONSTEXPR basic_string&
operator=(value_type const* rhs) { operator=(value_type const* rhs) {
return assign(rhs); return assign(rhs);
} }
basic_string& SPROUT_CXX14_CONSTEXPR basic_string&
operator=(value_type rhs) { operator=(value_type rhs) {
return assign(1, rhs); return assign(1, rhs);
} }
// iterators: // iterators:
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION #if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
iterator SPROUT_CXX14_CONSTEXPR iterator
begin() SPROUT_NOEXCEPT { begin() SPROUT_NOEXCEPT {
return iterator(*this, 0); return iterator(*this, 0);
} }
@ -398,7 +397,7 @@ namespace sprout {
begin() const SPROUT_NOEXCEPT { begin() const SPROUT_NOEXCEPT {
return const_iterator(*this, 0); return const_iterator(*this, 0);
} }
iterator SPROUT_CXX14_CONSTEXPR iterator
end() SPROUT_NOEXCEPT { end() SPROUT_NOEXCEPT {
return iterator(*this, size()); return iterator(*this, size());
} }
@ -407,7 +406,7 @@ namespace sprout {
return const_iterator(*this, size()); return const_iterator(*this, size());
} }
#else #else
iterator SPROUT_CXX14_CONSTEXPR iterator
begin() SPROUT_NOEXCEPT { begin() SPROUT_NOEXCEPT {
return data(); return data();
} }
@ -415,8 +414,8 @@ namespace sprout {
begin() const SPROUT_NOEXCEPT { begin() const SPROUT_NOEXCEPT {
return data(); return data();
} }
iterator end() SPROUT_CXX14_CONSTEXPR iterator
SPROUT_NOEXCEPT { end() SPROUT_NOEXCEPT {
return data() + size(); return data() + size();
} }
SPROUT_CONSTEXPR const_iterator SPROUT_CONSTEXPR const_iterator
@ -424,7 +423,7 @@ namespace sprout {
return data() + size(); return data() + size();
} }
#endif #endif
reverse_iterator SPROUT_CXX14_CONSTEXPR reverse_iterator
rbegin() SPROUT_NOEXCEPT { rbegin() SPROUT_NOEXCEPT {
return const_reverse_iterator(end()); return const_reverse_iterator(end());
} }
@ -432,7 +431,7 @@ namespace sprout {
rbegin() const SPROUT_NOEXCEPT { rbegin() const SPROUT_NOEXCEPT {
return const_reverse_iterator(end()); return const_reverse_iterator(end());
} }
reverse_iterator SPROUT_CXX14_CONSTEXPR reverse_iterator
rend() SPROUT_NOEXCEPT { rend() SPROUT_NOEXCEPT {
return const_reverse_iterator(begin()); return const_reverse_iterator(begin());
} }
@ -480,7 +479,7 @@ namespace sprout {
max_size() const SPROUT_NOEXCEPT { max_size() const SPROUT_NOEXCEPT {
return static_size; return static_size;
} }
void SPROUT_CXX14_CONSTEXPR void
resize(size_type n, value_type c) { resize(size_type n, value_type c) {
lengthcheck(n); lengthcheck(n);
if (n > size()) { if (n > size()) {
@ -489,11 +488,11 @@ namespace sprout {
traits_type::assign(begin() + n, static_size - n, value_type()); traits_type::assign(begin() + n, static_size - n, value_type());
len = n; len = n;
} }
void SPROUT_CXX14_CONSTEXPR void
resize(size_type n) { resize(size_type n) {
resize(n, value_type()); resize(n, value_type());
} }
void SPROUT_CXX14_CONSTEXPR void
clear() SPROUT_NOEXCEPT { clear() SPROUT_NOEXCEPT {
traits_type::assign(begin(), static_size, value_type()); traits_type::assign(begin(), static_size, value_type());
len = 0; len = 0;
@ -503,7 +502,7 @@ namespace sprout {
return size() == 0; return size() == 0;
} }
// element access: // element access:
reference SPROUT_CXX14_CONSTEXPR reference
operator[](size_type i) { operator[](size_type i) {
return elems[i]; return elems[i];
} }
@ -511,7 +510,7 @@ namespace sprout {
operator[](size_type i) const { operator[](size_type i) const {
return elems[i]; return elems[i];
} }
reference SPROUT_CXX14_CONSTEXPR reference
at(size_type i) { at(size_type i) {
return i < size() ? elems[i] return i < size() ? elems[i]
: (throw std::out_of_range("basic_string<>: index out of range"), elems[i]) : (throw std::out_of_range("basic_string<>: index out of range"), elems[i])
@ -523,7 +522,7 @@ namespace sprout {
: (throw std::out_of_range("basic_string<>: index out of range"), elems[i]) : (throw std::out_of_range("basic_string<>: index out of range"), elems[i])
; ;
} }
reference SPROUT_CXX14_CONSTEXPR reference
front() { front() {
return elems[0]; return elems[0];
} }
@ -531,7 +530,7 @@ namespace sprout {
front() const { front() const {
return elems[0]; return elems[0];
} }
reference SPROUT_CXX14_CONSTEXPR reference
back() { back() {
return elems[size() - 1]; return elems[size() - 1];
} }
@ -541,19 +540,19 @@ namespace sprout {
} }
// modifiers: // modifiers:
template<std::size_t N2> template<std::size_t N2>
basic_string& SPROUT_CXX14_CONSTEXPR basic_string&
assign(basic_string<T, N2, Traits> const& str) { assign(basic_string<T, N2, Traits> const& str) {
return assign(str, 0, npos); return assign(str, 0, npos);
} }
template<std::size_t N2> template<std::size_t N2>
basic_string& SPROUT_CXX14_CONSTEXPR basic_string&
assign(basic_string<T, N2, Traits> const& str, size_type pos, size_type n) { assign(basic_string<T, N2, Traits> const& str, size_type pos, size_type n) {
if (str.size() < pos) { if (str.size() < pos) {
throw std::out_of_range("basic_string<>: index out of range"); throw std::out_of_range("basic_string<>: index out of range");
} }
return assign(str.begin() + pos, NS_SSCRISK_CEL_OR_SPROUT::min(n, str.size() - pos)); return assign(str.begin() + pos, NS_SSCRISK_CEL_OR_SPROUT::min(n, str.size() - pos));
} }
basic_string& SPROUT_CXX14_CONSTEXPR basic_string&
assign(value_type const* s, size_type n) { assign(value_type const* s, size_type n) {
lengthcheck(n); lengthcheck(n);
for (size_type i = 0; i < n; ++i) { for (size_type i = 0; i < n; ++i) {
@ -565,11 +564,11 @@ namespace sprout {
len = n; len = n;
return *this; return *this;
} }
basic_string& SPROUT_CXX14_CONSTEXPR basic_string&
assign(value_type const* s) { assign(value_type const* s) {
return assign(s, traits_type::length(s)); return assign(s, traits_type::length(s));
} }
basic_string& SPROUT_CXX14_CONSTEXPR basic_string&
assign(size_type n, value_type c) { assign(size_type n, value_type c) {
maxcheck(n); maxcheck(n);
traits_type::assign(begin(), n, c); traits_type::assign(begin(), n, c);
@ -578,7 +577,7 @@ namespace sprout {
return *this; return *this;
} }
template<typename InputIterator> template<typename InputIterator>
basic_string& SPROUT_CXX14_CONSTEXPR basic_string&
assign(InputIterator first, InputIterator last) { assign(InputIterator first, InputIterator last) {
size_type n = 0; size_type n = 0;
for (; n < static_size || first != last; ++n, ++first) { for (; n < static_size || first != last; ++n, ++first) {
@ -590,11 +589,11 @@ namespace sprout {
len = n; len = n;
return *this; return *this;
} }
void SPROUT_CXX14_CONSTEXPR void
swap(basic_string& other) swap(basic_string& other)
SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(std::swap(std::declval<T&>(), std::declval<T&>()))) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::swap(std::declval<T&>(), std::declval<T&>())))
{ {
std::swap_ranges(other.begin(), other.begin() + other.max_size(), begin()); sprout::swap_ranges(other.begin(), other.begin() + other.max_size(), begin());
sprout::swap(len, other.len); sprout::swap(len, other.len);
} }
// string operations: // string operations:
@ -602,7 +601,7 @@ namespace sprout {
c_str() const SPROUT_NOEXCEPT { c_str() const SPROUT_NOEXCEPT {
return data(); return data();
} }
pointer SPROUT_CXX14_CONSTEXPR pointer
data() SPROUT_NOEXCEPT { data() SPROUT_NOEXCEPT {
return &elems[0]; return &elems[0];
} }
@ -610,7 +609,7 @@ namespace sprout {
data() const SPROUT_NOEXCEPT { data() const SPROUT_NOEXCEPT {
return &elems[0]; return &elems[0];
} }
pointer SPROUT_CXX14_CONSTEXPR pointer
c_array() SPROUT_NOEXCEPT { c_array() SPROUT_NOEXCEPT {
return &elems[0]; return &elems[0];
} }
@ -765,7 +764,7 @@ namespace sprout {
return std::basic_string<T, Traits, Allocator>(data(), size()); return std::basic_string<T, Traits, Allocator>(data(), size());
} }
void SPROUT_CXX14_CONSTEXPR void
rangecheck(size_type i) const { rangecheck(size_type i) const {
if (i >= size()) { if (i >= size()) {
throw std::out_of_range("basic_string<>: index out of range"); throw std::out_of_range("basic_string<>: index out of range");
@ -775,7 +774,7 @@ namespace sprout {
#if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION #if SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION
// construct/copy/destroy (for string iterator): // construct/copy/destroy (for string iterator):
template<typename StringConstIterator> template<typename StringConstIterator>
typename std::enable_if< SPROUT_CXX14_CONSTEXPR typename std::enable_if<
is_string_iterator<StringConstIterator>::value, is_string_iterator<StringConstIterator>::value,
basic_string& basic_string&
>::type >::type
@ -785,7 +784,7 @@ namespace sprout {
// modifiers (for string iterator): // modifiers (for string iterator):
template<typename StringConstIterator> template<typename StringConstIterator>
typename std::enable_if< SPROUT_CXX14_CONSTEXPR typename std::enable_if<
is_string_iterator<StringConstIterator>::value, is_string_iterator<StringConstIterator>::value,
basic_string& basic_string&
>::type >::type
@ -801,7 +800,7 @@ namespace sprout {
return *this; return *this;
} }
template<typename StringConstIterator> template<typename StringConstIterator>
typename std::enable_if< SPROUT_CXX14_CONSTEXPR typename std::enable_if<
is_string_iterator<StringConstIterator>::value, is_string_iterator<StringConstIterator>::value,
basic_string& basic_string&
>::type >::type
@ -944,7 +943,7 @@ namespace sprout {
// swap // swap
// //
template<typename T, std::size_t N, typename Traits> template<typename T, std::size_t N, typename Traits>
inline void inline SPROUT_CXX14_CONSTEXPR void
swap(sprout::basic_string<T, N, Traits>& lhs, sprout::basic_string<T, N, Traits>& rhs) swap(sprout::basic_string<T, N, Traits>& lhs, sprout::basic_string<T, N, Traits>& rhs)
SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs)))
{ {