@@ -880,19 +880,21 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
*/
#if __cplusplus >= 201103L
_Tp*
-#else
- pointer
-#endif
data() _GLIBCXX_NOEXCEPT
- { return std::__addressof(front()); }
+ { return empty() ? nullptr : std::__addressof(*this->_M_impl._M_start); }
-#if __cplusplus >= 201103L
const _Tp*
+ data() const _GLIBCXX_NOEXCEPT
+ { return empty() ? nullptr : std::__addressof(*this->_M_impl._M_start); }
#else
+ pointer
+ data() _GLIBCXX_NOEXCEPT
+ { return this->_M_impl._M_start; }
+
const_pointer
-#endif
data() const _GLIBCXX_NOEXCEPT
- { return std::__addressof(front()); }
+ { return this->_M_impl._M_start; }
+#endif
// [23.2.4.3] modifiers
/**
new file mode 100644
@@ -0,0 +1,108 @@
+// Copyright (C) 2014 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++11" }
+
+// libstdc++/59829
+
+#include <vector>
+
+// User-defined pointer type that throws if a null pointer is dereferenced.
+template<typename T>
+struct Pointer
+{
+ typedef T element_type;
+
+ // typedefs for iterator_traits
+ typedef T value_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef Pointer pointer;
+ typedef T& reference;
+
+ T* value;
+
+ explicit Pointer(T* p = nullptr) : value(p) { }
+
+ template<typename U, typename Requires = decltype((T*)std::declval<U*>())>
+ Pointer(const Pointer<U>& p) : value(p.value) { }
+
+ T& operator*() const
+ {
+ if (!value)
+ throw nullptr;
+ return *value;
+ }
+
+ T* operator->() const { return value; }
+
+ Pointer& operator++() { ++value; return *this; }
+ Pointer operator++(int) { Pointer tmp(*this); ++value; return tmp; }
+ Pointer& operator--() { --value; return *this; }
+ Pointer operator--(int) { Pointer tmp(*this); --value; return tmp; }
+
+ Pointer& operator+=(difference_type n) { value += n; return *this; }
+ Pointer& operator-=(difference_type n) { value -= n; return *this; }
+
+ explicit operator bool() const { return value != nullptr; }
+
+ Pointer operator+(difference_type n) { Pointer p(*this); return p += n; }
+ Pointer operator-(difference_type n) { Pointer p(*this); return p -= n; }
+};
+
+template<typename T>
+std::ptrdiff_t operator-(Pointer<T> l, Pointer<T> r)
+{ return l.value - r.value; }
+
+template<typename T>
+bool operator==(Pointer<T> l, Pointer<T> r)
+{ return l.value == r.value; }
+
+template<typename T>
+bool operator!=(Pointer<T> l, Pointer<T> r)
+{ return l.value != r.value; }
+
+template<typename T>
+struct Alloc
+{
+ typedef T value_type;
+ typedef Pointer<T> pointer;
+
+ Alloc() = default;
+ template<typename U>
+ Alloc(const Alloc<U>&) { }
+
+ pointer allocate(std::size_t n)
+ { return pointer(std::allocator<T>().allocate(n)); }
+
+ void deallocate(pointer p, std::size_t n)
+ { std::allocator<T>().deallocate(p.value, n); }
+};
+
+template<typename T>
+bool operator==(Alloc<T> l, Alloc<T> r)
+{ return true; }
+
+template<typename T>
+bool operator!=(Alloc<T> l, Alloc<T> r)
+{ return false; }
+
+int main()
+{
+ std::vector<int, Alloc<int>> a;
+ a.data();
+}