[libcxx-commits] [PATCH] D60105: Fix vector<bool>::const_reference to be 'bool'.

Eric Fiselier via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Mon Apr 1 16:41:33 PDT 2019


EricWF created this revision.
EricWF added reviewers: mclow.lists, ldionne.
Herald added a subscriber: dexonsmith.

  Our vector<bool>::const_reference is non-conforming because the standard requires it to be `bool` but we define it as a bit wrapper type.
   

This patch changes the `const_reference` typedef guarded under the ABI flag _LIBCPP_ABI_VECTOR_BOOL_CORRECT_CONST_REFERENCE_TYPE.


Repository:
  rCXX libc++

https://reviews.llvm.org/D60105

Files:
  include/__config
  include/vector
  test/std/containers/sequences/vector.bool/insert_iter_size_value.pass.cpp
  test/std/containers/sequences/vector.bool/types.pass.cpp


Index: test/std/containers/sequences/vector.bool/types.pass.cpp
===================================================================
--- test/std/containers/sequences/vector.bool/types.pass.cpp
+++ test/std/containers/sequences/vector.bool/types.pass.cpp
@@ -65,6 +65,11 @@
     static_assert((std::is_same<
         typename C::const_reverse_iterator,
         std::reverse_iterator<typename C::const_iterator> >::value), "");
+
+#if !defined(_LIBCPP_VERSION) ||                                               \
+    defined(_LIBCPP_ABI_VECTOR_BOOL_CORRECT_CONST_REFERENCE_TYPE)
+    static_assert((std::is_same<typename C::const_reference, bool>::value), "");
+#endif
 }
 
 int main(int, char**)
Index: test/std/containers/sequences/vector.bool/insert_iter_size_value.pass.cpp
===================================================================
--- test/std/containers/sequences/vector.bool/insert_iter_size_value.pass.cpp
+++ test/std/containers/sequences/vector.bool/insert_iter_size_value.pass.cpp
@@ -63,6 +63,12 @@
         for (++j; j < v.size(); ++j)
             assert(v[j] == 0);
     }
+    {
+      std::vector<bool> v(100);
+      const auto& cv = v;
+      std::vector<bool> v2;
+      v2.insert(v2.begin(), 3, cv[0]);
+    }
 #if TEST_STD_VER >= 11
     {
         std::vector<bool, min_allocator<bool>> v(100);
Index: include/vector
===================================================================
--- include/vector
+++ include/vector
@@ -2217,8 +2217,13 @@
     size_type                                              __size_;
     __compressed_pair<size_type, __storage_allocator> __cap_alloc_;
 public:
-    typedef __bit_reference<vector>                  reference;
-    typedef __bit_const_reference<vector>            const_reference;
+  typedef __bit_const_reference<vector> __const_ref;
+  typedef __bit_reference<vector> reference;
+#ifdef _LIBCPP_ABI_VECTOR_BOOL_CORRECT_CONST_REFERENCE_TYPE
+  typedef bool const_reference;
+#else
+  typedef __bit_const_reference<vector> const_reference;
+#endif
 private:
     _LIBCPP_INLINE_VISIBILITY
     size_type& __cap() _NOEXCEPT
@@ -2415,7 +2420,7 @@
 
     iterator insert(const_iterator __position, const value_type& __x);
     iterator insert(const_iterator __position, size_type __n, const value_type& __x);
-    iterator insert(const_iterator __position, size_type __n, const_reference __x);
+
     template <class _InputIterator>
         typename enable_if
         <
@@ -2479,8 +2484,10 @@
     reference __make_ref(size_type __pos) _NOEXCEPT
         {return reference(__begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);}
     _LIBCPP_INLINE_VISIBILITY
-    const_reference __make_ref(size_type __pos) const _NOEXCEPT
-        {return const_reference(__begin_ + __pos / __bits_per_word, __storage_type(1) << __pos % __bits_per_word);}
+    __const_ref __make_ref(size_type __pos) const _NOEXCEPT {
+      return __const_ref(__begin_ + __pos / __bits_per_word,
+                         __storage_type(1) << __pos % __bits_per_word);
+    }
     _LIBCPP_INLINE_VISIBILITY
     iterator __make_iter(size_type __pos) _NOEXCEPT
         {return iterator(__begin_ + __pos / __bits_per_word, static_cast<unsigned>(__pos % __bits_per_word));}
Index: include/__config
===================================================================
--- include/__config
+++ include/__config
@@ -65,7 +65,7 @@
 #else
 #  error Unknown object file format
 #endif
-
+#define _LIBCPP_ABI_VECTOR_BOOL_CORRECT_CONST_REFERENCE_TYPE
 #if defined(_LIBCPP_ABI_UNSTABLE) || _LIBCPP_ABI_VERSION >= 2
 // Change short string representation so that string data starts at offset 0,
 // improving its alignment in some cases.
@@ -102,6 +102,8 @@
 #  define _LIBCPP_ABI_OPTIMIZED_FUNCTION
 // All the regex constants must be distinct and nonzero.
 #  define _LIBCPP_ABI_REGEX_CONSTANTS_NONZERO
+// Fix std::vector<bool>::const_reference to actually be a bool.
+#define _LIBCPP_ABI_VECTOR_BOOL_CORRECT_CONST_REFERENCE_TYPE
 #elif _LIBCPP_ABI_VERSION == 1
 #  if !defined(_LIBCPP_OBJECT_FORMAT_COFF)
 // Enable compiling copies of now inline methods into the dylib to support


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D60105.193200.patch
Type: text/x-patch
Size: 4150 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20190401/8a1d0b0d/attachment-0001.bin>


More information about the libcxx-commits mailing list