[NFC][libc++][bitset] Refactors constructors.
authorMark de Wever <koraq@xs4all.nl>
Sun, 9 Jul 2023 13:36:12 +0000 (15:36 +0200)
committerMark de Wever <koraq@xs4all.nl>
Sat, 15 Jul 2023 13:21:31 +0000 (15:21 +0200)
Based on the review comments in D153201 this combines the string and
c-string constructors. The common constructor is using a string_view:
- it allows propagating the _Traits, which are required to be used for
  comparison.
- it avoids allocating
- libc++ supports it in C++03

Reviewed By: philnik, #libc, ldionne

Differential Revision: https://reviews.llvm.org/D154860

libcxx/include/bitset
libcxx/test/libcxx/transitive_includes/cxx03.csv
libcxx/test/libcxx/transitive_includes/cxx11.csv
libcxx/test/libcxx/transitive_includes/cxx14.csv
libcxx/test/libcxx/transitive_includes/cxx17.csv
libcxx/test/libcxx/transitive_includes/cxx20.csv
libcxx/test/libcxx/transitive_includes/cxx23.csv
libcxx/test/libcxx/transitive_includes/cxx26.csv
libcxx/test/std/utilities/template.bitset/bitset.members/left_shift.pass.cpp

index afd95a7..c63ee22 100644 (file)
@@ -122,6 +122,7 @@ template <size_t N> struct hash<std::bitset<N>>;
 #include <climits>
 #include <cstddef>
 #include <stdexcept>
+#include <string_view>
 #include <version>
 
 // standard-mandated includes
@@ -691,18 +692,30 @@ public:
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR bitset() _NOEXCEPT {}
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
         bitset(unsigned long long __v) _NOEXCEPT : base(__v) {}
-    template<class _CharT, class = __enable_if_t<_IsCharLikeType<_CharT>::value> >
-    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
-        explicit bitset(const _CharT* __str,
-                        typename basic_string<_CharT>::size_type __n = basic_string<_CharT>::npos,
-                        _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'));
-    template<class _CharT, class _Traits, class _Allocator>
-    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
-        explicit bitset(const basic_string<_CharT,_Traits,_Allocator>& __str,
-                        typename basic_string<_CharT,_Traits,_Allocator>::size_type __pos = 0,
-                        typename basic_string<_CharT,_Traits,_Allocator>::size_type __n =
-                                (basic_string<_CharT,_Traits,_Allocator>::npos),
-                        _CharT __zero = _CharT('0'), _CharT __one = _CharT('1'));
+    template <class _CharT, class = __enable_if_t<_IsCharLikeType<_CharT>::value> >
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit bitset(
+        const _CharT* __str,
+        typename basic_string<_CharT>::size_type __n = basic_string<_CharT>::npos,
+        _CharT __zero                                = _CharT('0'),
+        _CharT __one                                 = _CharT('1')) {
+
+        size_t __rlen = std::min(__n, char_traits<_CharT>::length(__str));
+        __init_from_string_view(basic_string_view<_CharT>(__str, __rlen), __zero, __one);
+    }
+    template <class _CharT, class _Traits, class _Allocator>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 explicit bitset(
+        const basic_string<_CharT, _Traits, _Allocator>& __str,
+        typename basic_string<_CharT, _Traits, _Allocator>::size_type __pos = 0,
+        typename basic_string<_CharT, _Traits, _Allocator>::size_type __n =
+            basic_string<_CharT, _Traits, _Allocator>::npos,
+        _CharT __zero = _CharT('0'),
+        _CharT __one  = _CharT('1')) {
+        if (__pos > __str.size())
+            std::__throw_out_of_range("bitset string pos out of range");
+
+        size_t __rlen = std::min(__n, __str.size() - __pos);
+        __init_from_string_view(basic_string_view<_CharT, _Traits>(__str.data() + __pos, __rlen), __zero, __one);
+    }
 
     // 23.3.5.2 bitset operations:
     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX23
@@ -778,6 +791,22 @@ public:
     bitset operator>>(size_t __pos) const _NOEXCEPT;
 
 private:
+    template <class _CharT, class _Traits>
+    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 void
+    __init_from_string_view(basic_string_view<_CharT, _Traits> __str, _CharT __zero, _CharT __one) {
+
+        for (size_t __i = 0; __i < __str.size(); ++__i)
+            if (!_Traits::eq(__str[__i], __zero) && !_Traits::eq(__str[__i], __one))
+              std::__throw_invalid_argument("bitset string ctor has invalid argument");
+
+        size_t __mp = std::min(__str.size(), _Size);
+        size_t __i  = 0;
+        for (; __i < __mp; ++__i) {
+            _CharT __c   = __str[__mp - 1 - __i];
+            (*this)[__i] = _Traits::eq(__c, __one);
+        }
+        std::fill(base::__make_iter(__i), base::__make_iter(_Size), false);
+    }
 
     _LIBCPP_INLINE_VISIBILITY
     size_t __hash_code() const _NOEXCEPT {return base::__hash_code();}
@@ -786,54 +815,6 @@ private:
 };
 
 template <size_t _Size>
-template<class _CharT, class>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
-bitset<_Size>::bitset(const _CharT* __str,
-                      typename basic_string<_CharT>::size_type __n,
-                      _CharT __zero, _CharT __one)
-{
-    size_t __rlen = _VSTD::min(__n, char_traits<_CharT>::length(__str));
-    for (size_t __i = 0; __i < __rlen; ++__i)
-        if (__str[__i] != __zero && __str[__i] != __one)
-            __throw_invalid_argument("bitset string ctor has invalid argument");
-
-    size_t __mp = _VSTD::min(__rlen, _Size);
-    size_t __i = 0;
-    for (; __i < __mp; ++__i)
-    {
-        _CharT __c = __str[__mp - 1 - __i];
-        (*this)[__i] = (__c == __one);
-    }
-    _VSTD::fill(base::__make_iter(__i), base::__make_iter(_Size), false);
-}
-
-template <size_t _Size>
-template<class _CharT, class _Traits, class _Allocator>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
-bitset<_Size>::bitset(const basic_string<_CharT,_Traits,_Allocator>& __str,
-       typename basic_string<_CharT,_Traits,_Allocator>::size_type __pos,
-       typename basic_string<_CharT,_Traits,_Allocator>::size_type __n,
-       _CharT __zero, _CharT __one)
-{
-    if (__pos > __str.size())
-        __throw_out_of_range("bitset string pos out of range");
-
-    size_t __rlen = _VSTD::min(__n, __str.size() - __pos);
-    for (size_t __i = __pos; __i < __pos + __rlen; ++__i)
-        if (!_Traits::eq(__str[__i], __zero) && !_Traits::eq(__str[__i], __one))
-            __throw_invalid_argument("bitset string ctor has invalid argument");
-
-    size_t __mp = _VSTD::min(__rlen, _Size);
-    size_t __i = 0;
-    for (; __i < __mp; ++__i)
-    {
-        _CharT __c = __str[__pos + __mp - 1 - __i];
-        (*this)[__i] = _Traits::eq(__c, __one);
-    }
-    _VSTD::fill(base::__make_iter(__i), base::__make_iter(_Size), false);
-}
-
-template <size_t _Size>
 inline
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23
 bitset<_Size>&
index a833d81..93838aa 100644 (file)
@@ -95,6 +95,7 @@ bitset limits
 bitset new
 bitset stdexcept
 bitset string
+bitset string_view
 bitset type_traits
 bitset version
 ccomplex complex
index 9b6dab0..75da229 100644 (file)
@@ -95,6 +95,7 @@ bitset limits
 bitset new
 bitset stdexcept
 bitset string
+bitset string_view
 bitset type_traits
 bitset version
 ccomplex complex
index f80e0f3..1e6e53b 100644 (file)
@@ -95,6 +95,7 @@ bitset limits
 bitset new
 bitset stdexcept
 bitset string
+bitset string_view
 bitset type_traits
 bitset version
 ccomplex complex
index f80e0f3..1e6e53b 100644 (file)
@@ -95,6 +95,7 @@ bitset limits
 bitset new
 bitset stdexcept
 bitset string
+bitset string_view
 bitset type_traits
 bitset version
 ccomplex complex
index 4cfa114..d4c65b9 100644 (file)
@@ -94,6 +94,7 @@ bitset limits
 bitset new
 bitset stdexcept
 bitset string
+bitset string_view
 bitset type_traits
 bitset version
 ccomplex complex
index 0509207..4dc13cc 100644 (file)
@@ -56,6 +56,7 @@ bitset limits
 bitset new
 bitset stdexcept
 bitset string
+bitset string_view
 bitset version
 ccomplex complex
 charconv cerrno
index 0509207..4dc13cc 100644 (file)
@@ -56,6 +56,7 @@ bitset limits
 bitset new
 bitset stdexcept
 bitset string
+bitset string_view
 bitset version
 ccomplex complex
 charconv cerrno
index 64c2a2c..68ef5a6 100644 (file)
@@ -6,6 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+// The CI "Apple back-deployment with assertions enabled" needs a higher value
+// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=12712420
+
 // bitset<N> operator<<(size_t pos) const; // constexpr since C++23
 
 #include <bitset>