Skip to content

Commit bc1b45e

Browse files
committed
Make find() constexpr in C++11 (#48, #49, thanks @eyalroz)
commit d934b1ac5b8c4ad30222d5fa89d610f74e1b005a Author: Eyal Rozenberg <eyalroz1@gmx.com> Date: Sat Feb 12 21:10:58 2022 +0200 Naive implementation of a `constexpr` alternative to `std::search()` for pairs of `basic_string_view`s, using the `basic_string_view::starts_with()` method.
1 parent 8d49a12 commit bc1b45e

File tree

1 file changed

+26
-7
lines changed

1 file changed

+26
-7
lines changed

include/nonstd/string_view.hpp

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,20 @@ template
547547
>
548548
class basic_string_view;
549549

550+
#if nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER
551+
namespace detail {
552+
553+
template <class CharT, class Traits = std::char_traits<CharT> >
554+
constexpr const CharT* search(basic_string_view<CharT, Traits> haystack, basic_string_view<CharT, Traits> needle)
555+
{
556+
return haystack.starts_with(needle) ? haystack.begin() :
557+
haystack.empty() ? haystack.end() :
558+
search(haystack.substr(1), needle);
559+
}
560+
561+
} // namespace detail
562+
#endif
563+
550564
//
551565
// basic_string_view:
552566
//
@@ -572,7 +586,7 @@ class basic_string_view
572586
typedef const_pointer iterator;
573587
typedef const_pointer const_iterator;
574588
typedef std::reverse_iterator< const_iterator > reverse_iterator;
575-
typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
589+
typedef std::reverse_iterator< const_iterator > const_reverse_iterator;
576590

577591
typedef std::size_t size_type;
578592
typedef std::ptrdiff_t difference_type;
@@ -814,25 +828,30 @@ class basic_string_view
814828

815829
// find(), 4x:
816830

817-
nssv_constexpr14 size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
831+
nssv_constexpr size_type find( basic_string_view v, size_type pos = 0 ) const nssv_noexcept // (1)
818832
{
819833
return assert( v.size() == 0 || v.data() != nssv_nullptr )
820834
, pos >= size()
821-
? npos
822-
: to_pos( std::search( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq ) );
835+
? npos : to_pos(
836+
#if nssv_CPP11_OR_GREATER && ! nssv_CPP17_OR_GREATER
837+
detail::search( substr(pos), v )
838+
#else
839+
std::search( cbegin() + pos, cend(), v.cbegin(), v.cend(), Traits::eq )
840+
#endif
841+
);
823842
}
824843

825-
nssv_constexpr14 size_type find( CharT c, size_type pos = 0 ) const nssv_noexcept // (2)
844+
nssv_constexpr size_type find( CharT c, size_type pos = 0 ) const nssv_noexcept // (2)
826845
{
827846
return find( basic_string_view( &c, 1 ), pos );
828847
}
829848

830-
nssv_constexpr14 size_type find( CharT const * s, size_type pos, size_type n ) const // (3)
849+
nssv_constexpr size_type find( CharT const * s, size_type pos, size_type n ) const // (3)
831850
{
832851
return find( basic_string_view( s, n ), pos );
833852
}
834853

835-
nssv_constexpr14 size_type find( CharT const * s, size_type pos = 0 ) const // (4)
854+
nssv_constexpr size_type find( CharT const * s, size_type pos = 0 ) const // (4)
836855
{
837856
return find( basic_string_view( s ), pos );
838857
}

0 commit comments

Comments
 (0)