2019-09-09 13:56:14 -07:00
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
2019-11-06 18:58:22 -05:00
// Copyright (c) 2019 Krystian Stasiowski (sdkrystian at gmail dot com)
2019-09-09 13:56:14 -07:00
//
// 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)
//
2019-12-16 12:23:46 -05:00
// Official repository: https://github.com/boostorg/static_string
2019-09-09 13:56:14 -07:00
//
2019-12-16 12:23:46 -05:00
#ifndef BOOST_STATIC_STRING_IMPL_STATIC_STRING_HPP
#define BOOST_STATIC_STRING_IMPL_STATIC_STRING_HPP
2019-09-09 13:56:14 -07:00
2019-12-16 12:23:46 -05:00
#include <boost/static_string/config.hpp>
#include <boost/static_string/detail/static_string.hpp>
2019-09-09 13:56:14 -07:00
namespace boost {
2019-12-16 12:23:46 -05:00
namespace static_string {
2019-09-09 13:56:14 -07:00
2019-09-16 08:31:09 -07:00
//------------------------------------------------------------------------------
2019-09-09 13:56:14 -07:00
//
2019-09-16 08:31:09 -07:00
// Construction
2019-09-09 13:56:14 -07:00
//
2019-09-16 08:31:09 -07:00
//------------------------------------------------------------------------------
2019-09-09 13:56:14 -07:00
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP11_CONSTEXPR
basic_static_string < N , CharT , Traits >::
basic_static_string () noexcept
2019-09-09 13:56:14 -07:00
{
2019-12-16 12:23:46 -05:00
#ifdef BOOST_STATIC_STRING_CPP20_CONSTEXPR_USED
2020-01-01 15:01:39 -05:00
term ();
2019-12-16 00:51:47 -05:00
#endif
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string < N , CharT , Traits >::
2019-12-26 17:22:57 -05:00
basic_static_string ( size_type count , CharT ch ) BOOST_STATIC_STRING_COND_NOEXCEPT
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
assign ( count , ch );
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-09-09 13:56:14 -07:00
template < std :: size_t M >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string < N , CharT , Traits >::
basic_static_string ( basic_static_string < M , CharT , Traits > const & other ,
2019-12-26 17:22:57 -05:00
size_type pos ) BOOST_STATIC_STRING_COND_NOEXCEPT
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
assign ( other , pos );
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-09-09 13:56:14 -07:00
template < std :: size_t M >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string < N , CharT , Traits >::
basic_static_string (
basic_static_string < M , CharT , Traits > const & other ,
2019-09-13 14:27:09 -07:00
size_type pos ,
2019-12-26 17:22:57 -05:00
size_type count ) BOOST_STATIC_STRING_COND_NOEXCEPT
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
assign ( other , pos , count );
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string < N , CharT , Traits >::
2019-12-26 17:22:57 -05:00
basic_static_string ( CharT const * s , size_type count ) BOOST_STATIC_STRING_COND_NOEXCEPT
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
assign ( s , count );
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string < N , CharT , Traits >::
2019-12-26 17:22:57 -05:00
basic_static_string ( CharT const * s ) BOOST_STATIC_STRING_COND_NOEXCEPT
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
auto const count = Traits :: length ( s );
BOOST_STATIC_STRING_THROW_IF ( count > max_size (),
std :: length_error { "count > max_size()" });
2020-01-15 16:23:12 -05:00
Traits :: copy ( data (), s , count + 1 );
2020-01-01 15:01:39 -05:00
this -> set_size ( count );
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2020-01-15 16:23:12 -05:00
template < class InputIterator ,
typename std :: enable_if <
detail :: is_input_iterator < InputIterator >
:: value >:: type *>
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string < N , CharT , Traits >::
basic_static_string (
2019-11-08 21:16:41 -05:00
InputIterator first ,
2020-01-15 16:23:12 -05:00
InputIterator last ) BOOST_STATIC_STRING_COND_NOEXCEPT
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
assign ( first , last );
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string < N , CharT , Traits >::
basic_static_string (
basic_static_string const & s ) noexcept
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
assign ( s );
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-09-09 13:56:14 -07:00
template < std :: size_t M >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string < N , CharT , Traits >::
basic_static_string (
2019-12-26 17:22:57 -05:00
basic_static_string < M , CharT , Traits > const & s ) BOOST_STATIC_STRING_COND_NOEXCEPT
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
assign ( s );
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string < N , CharT , Traits >::
2019-12-26 17:22:57 -05:00
basic_static_string ( std :: initializer_list < CharT > init ) BOOST_STATIC_STRING_COND_NOEXCEPT
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
assign ( init . begin (), init . end ());
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string < N , CharT , Traits >::
2019-12-26 17:22:57 -05:00
basic_static_string ( string_view_type sv ) BOOST_STATIC_STRING_COND_NOEXCEPT
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
assign ( sv );
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-09-09 13:56:14 -07:00
template < class T , class >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
basic_static_string < N , CharT , Traits >::
2019-12-26 17:22:57 -05:00
basic_static_string ( T const & t , size_type pos , size_type n ) BOOST_STATIC_STRING_COND_NOEXCEPT
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
assign ( t , pos , n );
2019-09-09 13:56:14 -07:00
}
2019-09-16 08:31:09 -07:00
//------------------------------------------------------------------------------
2019-09-09 13:56:14 -07:00
//
2019-09-16 08:31:09 -07:00
// Assignment
2019-09-09 13:56:14 -07:00
//
2019-09-16 08:31:09 -07:00
//------------------------------------------------------------------------------
2019-09-09 13:56:14 -07:00
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-09-16 08:31:09 -07:00
assign (
size_type count ,
2019-12-26 17:22:57 -05:00
CharT ch ) BOOST_STATIC_STRING_COND_NOEXCEPT ->
2019-12-16 12:23:46 -05:00
basic_static_string &
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
BOOST_STATIC_STRING_THROW_IF ( count > max_size (),
std :: length_error { "count > max_size()" });
this -> set_size ( count );
Traits :: assign ( data (), size (), ch );
term ();
return * this ;
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-09-16 08:31:09 -07:00
assign (
2019-12-16 12:23:46 -05:00
basic_static_string const & s ) noexcept ->
basic_static_string &
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
if ( this == & s )
return * this ;
this -> set_size ( s . size ());
auto const n = size () + 1 ;
Traits :: copy ( data (), & s . data ()[ 0 ], n );
return * this ;
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-09-09 13:56:14 -07:00
template < std :: size_t M >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-09-16 08:31:09 -07:00
assign (
2019-12-16 12:23:46 -05:00
basic_static_string < M , CharT , Traits > const & s ,
2019-09-16 08:31:09 -07:00
size_type pos ,
2019-12-26 17:22:57 -05:00
size_type count ) BOOST_STATIC_STRING_COND_NOEXCEPT ->
2019-12-16 12:23:46 -05:00
basic_static_string &
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
auto const ss = s . subview ( pos , count );
return assign ( ss . data (), ss . size ());
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-09-16 08:31:09 -07:00
assign (
CharT const * s ,
2019-12-26 17:22:57 -05:00
size_type count ) BOOST_STATIC_STRING_COND_NOEXCEPT ->
2019-12-16 12:23:46 -05:00
basic_static_string &
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
BOOST_STATIC_STRING_THROW_IF ( count > max_size (),
std :: length_error { "count > max_size()" });
this -> set_size ( count );
Traits :: move ( data (), s , size ());
term ();
return * this ;
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-11-08 21:16:41 -05:00
template < class InputIterator >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-09-16 08:31:09 -07:00
assign (
2019-11-08 21:16:41 -05:00
InputIterator first ,
2019-12-26 17:22:57 -05:00
InputIterator last ) BOOST_STATIC_STRING_COND_NOEXCEPT ->
2019-09-16 08:31:09 -07:00
typename std :: enable_if <
2019-11-08 21:16:41 -05:00
detail :: is_input_iterator < InputIterator >:: value ,
2019-12-16 12:23:46 -05:00
basic_static_string &>:: type
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
auto ptr = data ();
for ( std :: size_t i = 0 ; first != last ; ++ first , ++ ptr , ++ i )
{
if ( 1 > max_size () - i )
2019-12-30 21:12:20 -05:00
{
2020-01-01 15:01:39 -05:00
this -> set_size ( i );
BOOST_STATIC_STRING_THROW ( std :: length_error { "n > max_size()" });
2019-12-30 21:12:20 -05:00
}
2020-01-01 15:01:39 -05:00
Traits :: assign ( * ptr , * first );
}
this -> set_size ( ptr - data ());
term ();
return * this ;
2019-09-09 13:56:14 -07:00
}
2019-09-16 08:31:09 -07:00
//------------------------------------------------------------------------------
2019-09-09 13:56:14 -07:00
//
// Element access
//
2019-09-16 08:31:09 -07:00
//------------------------------------------------------------------------------
2019-09-09 13:56:14 -07:00
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-12-26 17:22:57 -05:00
at ( size_type pos ) BOOST_STATIC_STRING_COND_NOEXCEPT ->
2019-09-09 13:56:14 -07:00
reference
{
2020-01-01 15:01:39 -05:00
BOOST_STATIC_STRING_THROW_IF (
pos >= size (), std :: out_of_range { "pos >= size()" });
return data ()[ pos ];
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-12-26 17:22:57 -05:00
at ( size_type pos ) const BOOST_STATIC_STRING_COND_NOEXCEPT ->
2019-09-09 13:56:14 -07:00
const_reference
{
2020-01-01 15:01:39 -05:00
BOOST_STATIC_STRING_THROW_IF (
pos >= size (), std :: out_of_range { "pos >= size()" });
return data ()[ pos ];
2019-09-09 13:56:14 -07:00
}
2019-09-16 08:31:09 -07:00
//------------------------------------------------------------------------------
2019-09-09 13:56:14 -07:00
//
// Capacity
//
2019-09-16 08:31:09 -07:00
//------------------------------------------------------------------------------
2019-09-09 13:56:14 -07:00
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
void
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-12-26 17:22:57 -05:00
reserve ( std :: size_t n ) BOOST_STATIC_STRING_COND_NOEXCEPT
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
BOOST_STATIC_STRING_THROW_IF (
n > max_size (), std :: length_error { "n > max_size()" });
2019-09-09 13:56:14 -07:00
}
2019-09-16 08:31:09 -07:00
//------------------------------------------------------------------------------
2019-09-09 13:56:14 -07:00
//
// Operations
//
2019-09-16 08:31:09 -07:00
//------------------------------------------------------------------------------
2019-09-09 13:56:14 -07:00
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
void
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-12-16 00:51:47 -05:00
clear () noexcept
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
this -> set_size ( 0 );
term ();
2019-09-09 13:56:14 -07:00
}
2019-09-16 08:31:09 -07:00
//------------------------------------------------------------------------------
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-09-16 08:31:09 -07:00
insert (
size_type index ,
CharT const * s ,
2019-12-26 17:22:57 -05:00
size_type count ) BOOST_STATIC_STRING_COND_NOEXCEPT ->
2019-12-16 12:23:46 -05:00
basic_static_string &
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
const auto curr_size = size ();
const auto curr_data = data ();
BOOST_STATIC_STRING_THROW_IF (
index > curr_size , std :: out_of_range { "index > size()" });
insert ( curr_data + index , s , s + count );
return * this ;
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-09-16 08:31:09 -07:00
insert (
const_iterator pos ,
size_type count ,
2019-12-26 17:22:57 -05:00
CharT ch ) BOOST_STATIC_STRING_COND_NOEXCEPT ->
2019-09-16 08:31:09 -07:00
iterator
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
const auto curr_size = size ();
const auto curr_data = data ();
BOOST_STATIC_STRING_THROW_IF (
count > max_size () - curr_size , std :: length_error { "count() > max_size() - size()" });
auto const index = pos - curr_data ;
Traits :: move ( & curr_data [ index + count ], & curr_data [ index ], curr_size - index );
Traits :: assign ( & curr_data [ index ], count , ch );
2020-01-03 16:06:12 -05:00
this -> set_size ( curr_size + count );
2020-01-01 15:01:39 -05:00
term ();
return & curr_data [ index ];
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-30 21:12:20 -05:00
template < class ForwardIterator >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-09-16 08:31:09 -07:00
insert (
const_iterator pos ,
2019-12-30 21:12:20 -05:00
ForwardIterator first ,
ForwardIterator last ) BOOST_STATIC_STRING_COND_NOEXCEPT ->
2019-09-16 08:31:09 -07:00
typename std :: enable_if <
2019-12-30 21:12:20 -05:00
detail :: is_forward_iterator <
ForwardIterator >:: value , iterator >:: type
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
const auto curr_size = size ();
const auto curr_data = data ();
const auto count = detail :: distance ( first , last );
const auto index = pos - curr_data ;
const auto s = &* first ;
BOOST_STATIC_STRING_THROW_IF (
count > max_size () - curr_size , std :: length_error { "count > max_size() - size()" });
2020-01-03 19:01:34 -05:00
// Makes this more constexpr friendly if we can use is_constant_evaluated
const bool inside =
#ifdef BOOST_STATIC_STRING_USE_IS_CONST_EVAL
std :: is_constant_evaluated () ?
detail :: is_inside ( curr_data , curr_data + curr_size , s ) :
s <= & curr_data [ curr_size ] && s >= curr_data ;
#else
s <= & curr_data [ curr_size ] && s >= curr_data ;
#endif
2020-01-01 15:01:39 -05:00
if ( ! inside || ( inside && (( s - curr_data ) + count <= index )))
{
Traits :: move ( & curr_data [ index + count ], & curr_data [ index ], curr_size - index + 1 );
detail :: copy_with_traits < Traits > ( first , last , & curr_data [ index ]);
}
else
{
const size_type offset = s - curr_data ;
Traits :: move ( & curr_data [ index + count ], & curr_data [ index ], curr_size - index + 1 );
if ( offset < index )
2019-12-30 16:44:17 -05:00
{
2020-01-01 15:01:39 -05:00
const size_type diff = index - offset ;
Traits :: copy ( & curr_data [ index ], & curr_data [ offset ], diff );
Traits :: copy ( & curr_data [ index + diff ], & curr_data [ index + count ], count - diff );
2019-12-30 16:44:17 -05:00
}
else
{
2020-01-01 15:01:39 -05:00
Traits :: copy ( & curr_data [ index ], & curr_data [ offset + count ], count );
2019-12-30 16:44:17 -05:00
}
2020-01-01 15:01:39 -05:00
}
this -> set_size ( curr_size + count );
return curr_data + index ;
2019-09-09 13:56:14 -07:00
}
2019-12-30 21:12:20 -05:00
template < std :: size_t N , typename CharT , typename Traits >
template < class InputIterator >
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string < N , CharT , Traits >::
insert (
const_iterator pos ,
InputIterator first ,
InputIterator last ) BOOST_STATIC_STRING_COND_NOEXCEPT ->
typename std :: enable_if <
detail :: is_input_iterator <
InputIterator >:: value &&
! detail :: is_forward_iterator <
InputIterator >:: value , iterator >:: type
{
2020-01-01 15:01:39 -05:00
const auto curr_size = size ();
const auto curr_data = data ();
const auto count = read_back ( first , last );
const auto index = pos - curr_data ;
const auto s = curr_data + curr_size + 1 ;
BOOST_STATIC_STRING_THROW_IF (
index > curr_size , std :: out_of_range { "index > size()" });
std :: rotate ( & curr_data [ index ], & curr_data [ curr_size + 1 ], & curr_data [ curr_size + count + 1 ]);
this -> set_size ( curr_size + count );
return curr_data + index ;
2019-12-30 21:12:20 -05:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-09-16 08:31:09 -07:00
insert (
2019-12-30 16:44:17 -05:00
const_iterator pos ,
std :: initializer_list < CharT > ilist ) BOOST_STATIC_STRING_COND_NOEXCEPT ->
iterator
2019-09-16 08:31:09 -07:00
{
2020-01-01 15:01:39 -05:00
const auto curr_size = size ();
const auto curr_data = data ();
const auto index = pos - curr_data ;
BOOST_STATIC_STRING_THROW_IF (
index > curr_size , std :: out_of_range { "index > size()" });
BOOST_STATIC_STRING_THROW_IF (
ilist . size () > max_size () - curr_size , std :: length_error { "count > max_size() - size()" });
Traits :: move ( & curr_data [ index + ilist . size ()], & curr_data [ index ], curr_size - index + 1 );
detail :: copy_with_traits < Traits > ( ilist . begin (), ilist . end (), & curr_data [ index ]);
this -> set_size ( curr_size + ilist . size ());
return curr_data + index ;
2019-09-09 13:56:14 -07:00
}
2019-09-16 08:31:09 -07:00
//------------------------------------------------------------------------------
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-09-16 08:31:09 -07:00
erase (
size_type index ,
2019-12-26 17:22:57 -05:00
size_type count ) BOOST_STATIC_STRING_COND_NOEXCEPT ->
2019-12-16 12:23:46 -05:00
basic_static_string &
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
const auto curr_size = size ();
const auto curr_data = data ();
BOOST_STATIC_STRING_THROW_IF (
index > curr_size , std :: out_of_range { "index > size()" });
auto const n = ( std :: min )( count , curr_size - index );
Traits :: move ( & curr_data [ index ], & curr_data [ index + n ], curr_size - ( index + n ) + 1 );
this -> set_size ( curr_size - n );
return * this ;
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-09-16 08:31:09 -07:00
erase (
2019-12-26 17:22:57 -05:00
const_iterator pos ) BOOST_STATIC_STRING_COND_NOEXCEPT ->
2019-09-16 08:31:09 -07:00
iterator
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
erase ( pos - begin (), 1 );
return begin () + ( pos - begin ());
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-09-16 08:31:09 -07:00
erase (
const_iterator first ,
2019-12-26 17:22:57 -05:00
const_iterator last ) BOOST_STATIC_STRING_COND_NOEXCEPT ->
2019-09-16 08:31:09 -07:00
iterator
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
erase ( first - begin (),
detail :: distance ( first , last ));
return begin () + ( first - begin ());
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
void
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-09-16 08:31:09 -07:00
push_back (
2019-12-26 17:22:57 -05:00
CharT ch ) BOOST_STATIC_STRING_COND_NOEXCEPT
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
const auto curr_size = size ();
BOOST_STATIC_STRING_THROW_IF (
curr_size >= max_size (), std :: length_error { "size() >= max_size()" });
Traits :: assign ( data ()[ curr_size ], ch );
this -> set_size ( curr_size + 1 );
term ();
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-09-16 08:31:09 -07:00
append (
CharT const * s ,
2019-12-26 17:22:57 -05:00
size_type count ) BOOST_STATIC_STRING_COND_NOEXCEPT ->
2019-12-16 12:23:46 -05:00
basic_static_string &
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
const auto curr_size = size ();
BOOST_STATIC_STRING_THROW_IF (
count > max_size () - curr_size , std :: length_error { "count > max_size() - size()" });
Traits :: copy ( & data ()[ curr_size ], s , count );
this -> set_size ( curr_size + count );
term ();
return * this ;
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-12-26 17:22:57 -05:00
substr ( size_type pos , size_type count ) const BOOST_STATIC_STRING_COND_NOEXCEPT ->
2019-12-16 12:23:46 -05:00
basic_static_string
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
BOOST_STATIC_STRING_THROW_IF (
pos > size (), std :: out_of_range { "pos > size()" });
return { & data ()[ pos ], ( std :: min )( count , size () - pos )};
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-12-26 17:22:57 -05:00
subview ( size_type pos , size_type count ) const BOOST_STATIC_STRING_COND_NOEXCEPT ->
2019-12-16 00:51:47 -05:00
string_view_type
{
2020-01-01 15:01:39 -05:00
BOOST_STATIC_STRING_THROW_IF (
pos > size (), std :: out_of_range { "pos > size()" });
return { & data ()[ pos ], ( std :: min )( count , size () - pos )};
2019-12-16 00:51:47 -05:00
}
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-12-16 00:51:47 -05:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-12-16 00:51:47 -05:00
copy ( CharT * dest , size_type count , size_type pos ) const noexcept ->
2019-09-09 13:56:14 -07:00
size_type
{
2020-01-01 15:01:39 -05:00
auto const s = subview ( pos , count );
Traits :: copy ( dest , s . data (), s . size ());
return s . size ();
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
void
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-12-26 17:22:57 -05:00
resize ( std :: size_t n ) BOOST_STATIC_STRING_COND_NOEXCEPT
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
const auto curr_size = size ();
BOOST_STATIC_STRING_THROW_IF (
n > max_size (), std :: length_error { "n > max_size()" });
if ( n > curr_size )
Traits :: assign ( & data ()[ curr_size ], n - curr_size , CharT {});
this -> set_size ( n );
term ();
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
void
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-12-26 17:22:57 -05:00
resize ( std :: size_t n , CharT c ) BOOST_STATIC_STRING_COND_NOEXCEPT
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
const auto curr_size = size ();
BOOST_STATIC_STRING_THROW_IF (
n > max_size (), std :: length_error { "n > max_size()" });
if ( n > curr_size )
Traits :: assign ( & data ()[ curr_size ], n - curr_size , c );
this -> set_size ( n );
term ();
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
void
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
swap ( basic_static_string & s ) noexcept
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
const auto curr_size = size ();
basic_static_string tmp ( s );
s . set_size ( curr_size );
Traits :: copy ( & s . data ()[ 0 ], data (), curr_size + 1 );
this -> set_size ( tmp . size ());
Traits :: copy ( data (), tmp . data (), size () + 1 );
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-09-09 13:56:14 -07:00
template < std :: size_t M >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
void
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-12-26 17:22:57 -05:00
swap ( basic_static_string < M , CharT , Traits >& s ) BOOST_STATIC_STRING_COND_NOEXCEPT
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
const auto curr_size = size ();
BOOST_STATIC_STRING_THROW_IF (
curr_size > s . max_size (), std :: length_error { "size() > s.max_size()" });
BOOST_STATIC_STRING_THROW_IF (
s . size () > max_size (), std :: length_error { "s.size() > max_size()" });
basic_static_string tmp ( s );
s . set_size ( curr_size );
Traits :: copy ( & s . data ()[ 0 ], data (), curr_size + 1 );
this -> set_size ( tmp . size ());
Traits :: copy ( data (), & tmp . data ()[ 0 ], size () + 1 );
2019-09-09 13:56:14 -07:00
}
2019-10-18 20:52:07 -04:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-10-18 20:50:42 -04:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-10-18 20:50:42 -04:00
replace (
size_type pos ,
size_type n1 ,
const CharT * s ,
2020-01-01 15:01:39 -05:00
size_type n2 ) BOOST_STATIC_STRING_COND_NOEXCEPT ->
basic_static_string < N , CharT , Traits >&
2019-10-18 20:50:42 -04:00
{
2020-01-01 15:01:39 -05:00
const auto curr_size = size ();
const auto curr_data = data ();
BOOST_STATIC_STRING_THROW_IF (
pos > curr_size , std :: out_of_range { "pos > size()" });
2020-01-03 18:43:59 -05:00
n1 = ( std :: min )( n1 , curr_size - pos );
2020-01-01 15:01:39 -05:00
return replace ( curr_data + pos , curr_data + pos + n1 , s , s + n2 );
2019-10-18 20:50:42 -04:00
}
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-10-18 20:50:42 -04:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-10-18 20:50:42 -04:00
replace (
size_type pos ,
size_type n1 ,
size_type n2 ,
2019-12-26 17:22:57 -05:00
CharT c ) BOOST_STATIC_STRING_COND_NOEXCEPT -> basic_static_string < N , CharT , Traits > &
2019-10-18 20:50:42 -04:00
{
2020-01-01 15:01:39 -05:00
const auto curr_size = size ();
const auto curr_data = data ();
BOOST_STATIC_STRING_THROW_IF (
pos > curr_size , std :: out_of_range { "pos > size()" });
BOOST_STATIC_STRING_THROW_IF (
curr_size - ( std :: min )( n1 , curr_size - pos ) >= max_size () - n2 ,
std :: length_error { "replaced string exceeds max_size()" });
2020-01-03 18:43:59 -05:00
n1 = ( std :: min )( n1 , curr_size - pos );
2020-01-01 15:01:39 -05:00
Traits :: move ( & curr_data [ pos + n2 ], & curr_data [ pos + n1 ], curr_size - pos - n1 + 1 );
Traits :: assign ( & curr_data [ pos ], n2 , c );
this -> set_size ( curr_size + ( n2 - n1 ));
return * this ;
2019-10-18 20:50:42 -04:00
}
2019-12-30 16:44:17 -05:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-30 21:12:20 -05:00
template < typename ForwardIterator >
2019-12-30 16:44:17 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string < N , CharT , Traits >::
replace (
const_iterator i1 ,
const_iterator i2 ,
2019-12-30 21:12:20 -05:00
ForwardIterator j1 ,
ForwardIterator j2 ) BOOST_STATIC_STRING_COND_NOEXCEPT ->
2019-12-30 16:44:17 -05:00
typename std :: enable_if <
2019-12-30 21:12:20 -05:00
detail :: is_forward_iterator < ForwardIterator >:: value ,
2019-12-30 16:44:17 -05:00
basic_static_string < N , CharT , Traits >&>:: type
{
2020-01-01 15:01:39 -05:00
const auto curr_size = size ();
const auto curr_data = data ();
std :: size_t n1 = detail :: distance ( i1 , i2 );
const std :: size_t n2 = detail :: distance ( j1 , j2 );
const std :: size_t pos = i1 - curr_data ;
const auto s = &* j1 ;
BOOST_STATIC_STRING_THROW_IF (
curr_size - ( std :: min )( n1 , curr_size - pos ) >= max_size () - n2 ,
std :: length_error { "replaced string exceeds max_size()" });
2020-01-03 18:43:59 -05:00
n1 = ( std :: min )( n1 , curr_size - pos );
2020-01-03 19:01:34 -05:00
// Makes this more constexpr friendly if we can use is_constant_evaluated
const bool inside =
#ifdef BOOST_STATIC_STRING_USE_IS_CONST_EVAL
std :: is_constant_evaluated () ?
detail :: is_inside ( curr_data , curr_data + curr_size , s ) :
s <= & curr_data [ curr_size ] && s >= curr_data ;
#else
s <= & curr_data [ curr_size ] && s >= curr_data ;
#endif
2020-01-01 15:01:39 -05:00
if ( inside && size_type ( s - curr_data ) == pos && n1 == n2 )
return * this ;
if ( ! inside || ( inside && (( s - curr_data ) + n2 <= pos )))
{
// source outside
Traits :: move ( & curr_data [ pos + n2 ], & curr_data [ pos + n1 ], curr_size - pos - n1 + 1 );
detail :: copy_with_traits < Traits > ( j1 , j2 , & curr_data [ pos ]);
}
else
{
// source inside
const size_type offset = s - curr_data ;
if ( n2 >= n1 )
2019-12-30 16:44:17 -05:00
{
2020-01-01 15:01:39 -05:00
// grow/unchanged
// shift all right of splice point by n2 - n1 to the right
2019-12-30 16:44:17 -05:00
Traits :: move ( & curr_data [ pos + n2 ], & curr_data [ pos + n1 ], curr_size - pos - n1 + 1 );
2020-01-01 15:01:39 -05:00
const size_type diff = offset <= pos + n1 ? ( std :: min )(( pos + n1 ) - offset , n2 ) : 0 ;
// copy all before splice point
Traits :: move ( & curr_data [ pos ], & curr_data [ offset ], diff );
// copy all after splice point
Traits :: move ( & curr_data [ pos + diff ], & curr_data [ offset + ( n2 - n1 ) + diff ], n2 - diff );
2019-12-30 16:44:17 -05:00
}
else
{
2020-01-01 15:01:39 -05:00
// shrink
// copy all elements into place
Traits :: move ( & curr_data [ pos ], & curr_data [ offset ], n2 );
// shift all elements after splice point left
Traits :: move ( & curr_data [ pos + n2 ], & curr_data [ pos + n1 ], curr_size - pos - n1 + 1 );
2019-12-30 16:44:17 -05:00
}
2020-01-01 15:01:39 -05:00
}
this -> set_size ( curr_size + ( n2 - n1 ));
return * this ;
2019-12-30 16:44:17 -05:00
}
2019-12-30 21:12:20 -05:00
template < std :: size_t N , typename CharT , typename Traits >
template < typename InputIterator >
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string < N , CharT , Traits >::
replace (
const_iterator i1 ,
const_iterator i2 ,
InputIterator j1 ,
InputIterator j2 ) BOOST_STATIC_STRING_COND_NOEXCEPT ->
typename std :: enable_if <
detail :: is_input_iterator <
InputIterator >:: value &&
! detail :: is_forward_iterator <
InputIterator >:: value ,
basic_static_string < N , CharT , Traits >&>:: type
2019-12-30 16:44:17 -05:00
{
const auto curr_size = size ();
const auto curr_data = data ();
std :: size_t n1 = detail :: distance ( i1 , i2 );
2020-01-01 15:01:39 -05:00
const std :: size_t n2 = read_back ( j1 , j2 );
2019-12-30 21:12:20 -05:00
const std :: size_t pos = i1 - curr_data ;
2019-12-30 16:44:17 -05:00
BOOST_STATIC_STRING_THROW_IF (
pos > curr_size , std :: out_of_range { "pos > size()" });
BOOST_STATIC_STRING_THROW_IF (
2020-01-01 15:01:39 -05:00
curr_size - ( std :: min )( n1 , curr_size - pos ) >= max_size () - n2 ,
2019-12-30 16:44:17 -05:00
std :: length_error { "replaced string exceeds max_size()" });
2020-01-01 15:01:39 -05:00
// Rotate to the correct order. [i2, end] will now start with the replaced string, continue to the existing string not being replaced, and end with a null terminator
std :: rotate ( & curr_data [ pos ], & curr_data [ curr_size + 1 ], & curr_data [ curr_size + n2 + 1 ]);
// Cap the size
2020-01-03 18:43:59 -05:00
n1 = ( std :: min )( n1 , curr_size - pos );
2020-01-01 15:01:39 -05:00
// Move everything from the end of the splice point to the end of the rotated string to the begining of the splice point
Traits :: move ( & curr_data [ pos + n2 ], & curr_data [ pos + n2 + n1 ], ( curr_size + ( n2 - n1 )) - pos );
this -> set_size ( curr_size + ( n2 - n1 ));
2019-12-30 16:44:17 -05:00
return * this ;
}
2019-10-27 16:12:06 -04:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-10-27 16:12:06 -04:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-10-27 16:12:06 -04:00
find (
const CharT * s ,
size_type pos ,
2019-12-16 00:51:47 -05:00
size_type n ) const noexcept ->
2019-10-27 16:12:06 -04:00
size_type
{
2020-01-01 15:01:39 -05:00
const auto curr_size = size ();
if ( pos > curr_size || n > curr_size - pos )
return npos ;
if ( ! n )
return pos ;
2020-01-03 16:59:34 -05:00
const auto res = detail :: search ( & data ()[ pos ], & data ()[ curr_size ], s , & s [ n ], Traits :: eq );
2020-01-01 15:01:39 -05:00
return res == end () ? npos : detail :: distance ( data (), res );
2019-10-27 16:12:06 -04:00
}
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-10-27 16:12:06 -04:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-10-27 16:12:06 -04:00
rfind (
const CharT * s ,
size_type pos ,
2019-12-16 00:51:47 -05:00
size_type n ) const noexcept ->
2019-10-27 16:12:06 -04:00
size_type
{
2020-01-01 15:01:39 -05:00
const auto curr_size = size ();
const auto curr_data = data ();
if ( curr_size < n )
2019-10-27 16:12:06 -04:00
return npos ;
2020-01-01 15:01:39 -05:00
if ( pos > curr_size - n )
pos = curr_size - n ;
if ( ! n )
return pos ;
for ( auto sub = & curr_data [ pos ]; sub >= curr_data ; -- sub )
if ( ! Traits :: compare ( sub , s , n ))
return detail :: distance ( curr_data , sub );
return npos ;
2019-10-27 16:12:06 -04:00
}
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-10-27 16:12:06 -04:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-10-27 16:12:06 -04:00
find_first_of (
const CharT * s ,
size_type pos ,
2019-12-16 00:51:47 -05:00
size_type n ) const noexcept ->
2019-10-27 16:12:06 -04:00
size_type
{
2020-01-01 15:01:39 -05:00
const auto curr_data = data ();
if ( pos >= size () || ! n )
return npos ;
2020-01-03 16:59:34 -05:00
const auto res = detail :: find_first_of ( & curr_data [ pos ], & curr_data [ size ()], s , & s [ n ], Traits :: eq );
2020-01-01 15:01:39 -05:00
return res == end () ? npos : detail :: distance ( curr_data , res );
2019-10-27 16:12:06 -04:00
}
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-10-27 16:12:06 -04:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-10-27 16:12:06 -04:00
find_last_of (
const CharT * s ,
size_type pos ,
2019-12-16 00:51:47 -05:00
size_type n ) const noexcept ->
2019-10-27 16:12:06 -04:00
size_type
{
2020-01-01 15:01:39 -05:00
const auto curr_size = size ();
if ( ! n )
return npos ;
if ( pos >= curr_size )
pos = 0 ;
else
pos = curr_size - ( pos + 1 );
2020-01-03 16:59:34 -05:00
const auto res = detail :: find_first_of ( rbegin () + pos , rend (), s , & s [ n ], Traits :: eq );
2020-01-01 15:01:39 -05:00
return res == rend () ? npos : curr_size - 1 - detail :: distance ( rbegin (), res );
2019-10-27 16:12:06 -04:00
}
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-10-27 16:12:06 -04:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-10-27 16:12:06 -04:00
find_first_not_of (
const CharT * s ,
size_type pos ,
2019-12-16 00:51:47 -05:00
size_type n ) const noexcept ->
2019-10-27 16:12:06 -04:00
size_type
{
2020-01-01 15:01:39 -05:00
if ( pos >= size ())
return npos ;
if ( ! n )
return pos ;
const auto res = detail :: find_not_of < Traits > ( & data ()[ pos ], & data ()[ size ()], s , n );
return res == end () ? npos : detail :: distance ( data (), res );
2019-10-27 16:12:06 -04:00
}
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-10-27 16:12:06 -04:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-10-27 16:12:06 -04:00
find_last_not_of (
const CharT * s ,
size_type pos ,
2019-12-16 00:51:47 -05:00
size_type n ) const noexcept ->
2019-10-27 16:12:06 -04:00
size_type
{
2020-01-01 15:01:39 -05:00
const auto curr_size = size ();
if ( pos >= curr_size )
pos = curr_size - 1 ;
if ( ! n )
return pos ;
pos = curr_size - ( pos + 1 );
const auto res = detail :: find_not_of < Traits > ( rbegin () + pos , rend (), s , n );
return res == rend () ? npos : curr_size - 1 - detail :: distance ( rbegin (), res );
2019-10-27 16:12:06 -04:00
}
2019-09-09 13:56:14 -07:00
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-12-16 12:23:46 -05:00
BOOST_STATIC_STRING_CPP14_CONSTEXPR
2019-09-09 13:56:14 -07:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-12-16 00:51:47 -05:00
assign_char ( CharT ch , std :: true_type ) noexcept ->
2019-12-16 12:23:46 -05:00
basic_static_string &
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
this -> set_size ( 1 );
Traits :: assign ( data ()[ 0 ], ch );
term ();
return * this ;
2019-09-09 13:56:14 -07:00
}
2019-09-13 14:27:09 -07:00
template < std :: size_t N , typename CharT , typename Traits >
2019-09-09 13:56:14 -07:00
auto
2019-12-16 12:23:46 -05:00
basic_static_string < N , CharT , Traits >::
2019-12-26 17:22:57 -05:00
assign_char ( CharT , std :: false_type ) BOOST_STATIC_STRING_COND_NOEXCEPT ->
2019-12-16 12:23:46 -05:00
basic_static_string &
2019-09-09 13:56:14 -07:00
{
2020-01-01 15:01:39 -05:00
BOOST_STATIC_STRING_THROW ( std :: length_error { "max_size() == 0" });
return * this ;
2019-09-09 13:56:14 -07:00
}
2019-12-30 21:12:20 -05:00
template < std :: size_t N , typename CharT , typename Traits >
template < typename InputIterator >
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string < N , CharT , Traits >::
read_back (
InputIterator first ,
InputIterator last ) ->
std :: size_t
{
const auto curr_data = data ();
auto new_size = size ();
for (; first != last ; ++ first )
{
BOOST_STATIC_STRING_THROW_IF (
1 > max_size () - new_size , std :: length_error { "count > max_size() - size()" });
Traits :: assign ( curr_data [ ++ new_size ], * first );
}
return new_size - size ();
}
2020-01-01 15:01:39 -05:00
template < std :: size_t N , typename CharT , typename Traits >
BOOST_STATIC_STRING_CPP14_CONSTEXPR
auto
basic_static_string < N , CharT , Traits >::
replace_unchecked (
size_type pos ,
size_type n1 ,
const CharT * s ,
size_type n2 ) BOOST_STATIC_STRING_COND_NOEXCEPT ->
basic_static_string &
{
const auto curr_data = data ();
const auto curr_size = size ();
BOOST_STATIC_STRING_THROW_IF (
pos > curr_size , std :: out_of_range { "pos > size()" });
BOOST_STATIC_STRING_THROW_IF (
curr_size - ( std :: min )( n1 , curr_size - pos ) >= max_size () - n2 ,
std :: length_error { "replaced string exceeds max_size()" });
if ( pos + n1 >= curr_size )
n1 = curr_size - pos ;
Traits :: move ( & curr_data [ pos + n2 ], & curr_data [ pos + n1 ], curr_size - pos - n1 + 1 );
Traits :: copy ( & curr_data [ pos ], s , n2 );
this -> set_size ( curr_size + ( n2 - n1 ));
return * this ;
}
2020-01-15 16:23:12 -05:00
// to_static_string
2019-12-20 02:34:04 -05:00
static_string < std :: numeric_limits < int >:: digits10 + 1 >
2019-10-27 21:01:44 -04:00
inline
2020-01-15 16:23:12 -05:00
to_static_string ( int value ) noexcept
2019-09-09 13:56:14 -07:00
{
2019-12-20 02:34:04 -05:00
return detail :: to_static_string_int_impl <
2019-12-20 18:21:28 -05:00
std :: numeric_limits < int >:: digits10 + 1 > ( value );
2019-12-20 02:34:04 -05:00
}
static_string < std :: numeric_limits < long >:: digits10 + 1 >
inline
2020-01-15 16:23:12 -05:00
to_static_string ( long value ) noexcept
2019-12-20 02:34:04 -05:00
{
return detail :: to_static_string_int_impl <
2019-12-20 18:21:28 -05:00
std :: numeric_limits < long >:: digits10 + 1 > ( value );
2019-12-20 02:34:04 -05:00
}
static_string < std :: numeric_limits < long long >:: digits10 + 1 >
inline
2020-01-15 16:23:12 -05:00
to_static_string ( long long value ) noexcept
2019-12-20 02:34:04 -05:00
{
return detail :: to_static_string_int_impl <
2019-12-20 18:21:28 -05:00
std :: numeric_limits < long long >:: digits10 + 1 > ( value );
2019-12-20 02:34:04 -05:00
}
static_string < std :: numeric_limits < unsigned int >:: digits10 + 1 >
inline
2020-01-15 16:23:12 -05:00
to_static_string ( unsigned int value ) noexcept
2019-12-20 02:34:04 -05:00
{
return detail :: to_static_string_int_impl <
2019-12-26 17:22:57 -05:00
std :: numeric_limits < unsigned int >:: digits10 + 1 > ( value );
2019-12-20 02:34:04 -05:00
}
static_string < std :: numeric_limits < unsigned long >:: digits10 + 1 >
inline
2020-01-15 16:23:12 -05:00
to_static_string ( unsigned long value ) noexcept
2019-12-20 02:34:04 -05:00
{
return detail :: to_static_string_int_impl <
2019-12-20 18:21:28 -05:00
std :: numeric_limits < unsigned long >:: digits10 + 1 > ( value );
2019-12-20 02:34:04 -05:00
}
static_string < std :: numeric_limits < unsigned long long >:: digits10 + 1 >
inline
2020-01-15 16:23:12 -05:00
to_static_string ( unsigned long long value ) noexcept
2019-12-20 02:34:04 -05:00
{
return detail :: to_static_string_int_impl <
2019-12-20 18:21:28 -05:00
std :: numeric_limits < unsigned long long >:: digits10 + 1 > ( value );
2019-12-20 02:34:04 -05:00
}
static_string < std :: numeric_limits < float >:: max_digits10 + 1 >
inline
2020-01-15 16:23:12 -05:00
to_static_string ( float value ) noexcept
2019-12-20 02:34:04 -05:00
{
return detail :: to_static_string_float_impl <
std :: numeric_limits < float >:: max_digits10 + 1 > ( value );
}
static_string < std :: numeric_limits < double >:: max_digits10 + 1 >
inline
2020-01-15 16:23:12 -05:00
to_static_string ( double value ) noexcept
2019-12-20 02:34:04 -05:00
{
return detail :: to_static_string_float_impl <
std :: numeric_limits < double >:: max_digits10 + 1 > ( value );
}
static_string < std :: numeric_limits < long double >:: max_digits10 + 1 >
inline
2020-01-15 16:23:12 -05:00
to_static_string ( long double value ) noexcept
2019-12-20 02:34:04 -05:00
{
return detail :: to_static_string_float_impl <
std :: numeric_limits < long double >:: max_digits10 + 1 > ( value );
}
2020-01-15 16:23:12 -05:00
// to_static_wstring
2019-12-20 02:34:04 -05:00
static_wstring < std :: numeric_limits < int >:: digits10 + 1 >
inline
2020-01-15 16:23:12 -05:00
to_static_wstring ( int value ) noexcept
2019-12-20 02:34:04 -05:00
{
return detail :: to_static_wstring_int_impl <
2019-12-20 18:21:28 -05:00
std :: numeric_limits < int >:: digits10 + 1 > ( value );
2019-12-20 02:34:04 -05:00
}
static_wstring < std :: numeric_limits < long >:: digits10 + 1 >
inline
2020-01-15 16:23:12 -05:00
to_static_wstring ( long value ) noexcept
2019-12-20 02:34:04 -05:00
{
return detail :: to_static_wstring_int_impl <
2019-12-20 18:21:28 -05:00
std :: numeric_limits < long >:: digits10 + 1 > ( value );
2019-12-20 02:34:04 -05:00
}
static_wstring < std :: numeric_limits < long long >:: digits10 + 1 >
inline
2020-01-15 16:23:12 -05:00
to_static_wstring ( long long value ) noexcept
2019-12-20 02:34:04 -05:00
{
return detail :: to_static_wstring_int_impl <
2019-12-26 17:22:57 -05:00
std :: numeric_limits < long long >:: digits10 + 1 > ( value );
2019-12-20 02:34:04 -05:00
}
static_wstring < std :: numeric_limits < unsigned int >:: digits10 + 1 >
inline
2020-01-15 16:23:12 -05:00
to_static_wstring ( unsigned int value ) noexcept
2019-12-20 02:34:04 -05:00
{
return detail :: to_static_wstring_int_impl <
2019-12-20 18:21:28 -05:00
std :: numeric_limits < unsigned int >:: digits10 + 1 > ( value );
2019-12-20 02:34:04 -05:00
}
static_wstring < std :: numeric_limits < unsigned long >:: digits10 + 1 >
inline
2020-01-15 16:23:12 -05:00
to_static_wstring ( unsigned long value ) noexcept
2019-12-20 02:34:04 -05:00
{
return detail :: to_static_wstring_int_impl <
2019-12-20 18:21:28 -05:00
std :: numeric_limits < unsigned long >:: digits10 + 1 > ( value );
2019-12-20 02:34:04 -05:00
}
static_wstring < std :: numeric_limits < unsigned long long >:: digits10 + 1 >
inline
2020-01-15 16:23:12 -05:00
to_static_wstring ( unsigned long long value ) noexcept
2019-12-20 02:34:04 -05:00
{
return detail :: to_static_wstring_int_impl <
2019-12-20 18:21:28 -05:00
std :: numeric_limits < unsigned long long >:: digits10 + 1 > ( value );
2019-12-20 02:34:04 -05:00
}
static_wstring < std :: numeric_limits < float >:: max_digits10 + 1 >
inline
2020-01-15 16:23:12 -05:00
to_static_wstring ( float value ) noexcept
2019-12-20 02:34:04 -05:00
{
return detail :: to_static_wstring_float_impl <
std :: numeric_limits < float >:: max_digits10 + 1 > ( value );
}
static_wstring < std :: numeric_limits < double >:: max_digits10 + 1 >
inline
2020-01-15 16:23:12 -05:00
to_static_wstring ( double value ) noexcept
2019-12-20 02:34:04 -05:00
{
return detail :: to_static_wstring_float_impl <
std :: numeric_limits < double >:: max_digits10 + 1 > ( value );
}
static_wstring < std :: numeric_limits < long double >:: max_digits10 + 1 >
inline
2020-01-15 16:23:12 -05:00
to_static_wstring ( long double value ) noexcept
2019-12-20 02:34:04 -05:00
{
return detail :: to_static_wstring_float_impl <
std :: numeric_limits < long double >:: max_digits10 + 1 > ( value );
2019-09-09 13:56:14 -07:00
}
2019-12-16 12:23:46 -05:00
} // static_string
2019-09-09 13:56:14 -07:00
} // boost
#endif