diff --git a/.clang-format b/.clang-format index 9b3aa8b72..28009ef37 100644 --- a/.clang-format +++ b/.clang-format @@ -1 +1,7 @@ BasedOnStyle: LLVM + +--- +Language: Cpp + +AlwaysBreakTemplateDeclarations: true +--- diff --git a/include/__hash_table b/include/__hash_table index 3072f93e0..0dc188b7a 100644 --- a/include/__hash_table +++ b/include/__hash_table @@ -1004,8 +1004,11 @@ public: _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT { - return allocator_traits<__pointer_allocator>::max_size( - __bucket_list_.get_deleter().__alloc()); + return std::min( + allocator_traits<__pointer_allocator>::max_size( + __bucket_list_.get_deleter().__alloc()), + numeric_limits::max() + ); } pair __node_insert_unique(__node_pointer __nd); @@ -1192,7 +1195,7 @@ public: _LIBCPP_INLINE_VISIBILITY size_type max_bucket_count() const _NOEXCEPT - {return __pointer_alloc_traits::max_size(__bucket_list_.get_deleter().__alloc());} + {return max_size(); } size_type bucket_size(size_type __n) const; _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT { diff --git a/include/__tree b/include/__tree index f3f68b559..4c94fe5a3 100644 --- a/include/__tree +++ b/include/__tree @@ -1106,7 +1106,9 @@ public: _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT - {return __node_traits::max_size(__node_alloc());} + {return std::min( + __node_traits::max_size(__node_alloc()), + numeric_limits::max());} void clear() _NOEXCEPT; diff --git a/include/deque b/include/deque index 9c72d24c2..f8e0bb870 100644 --- a/include/deque +++ b/include/deque @@ -1310,7 +1310,9 @@ public: size_type size() const _NOEXCEPT {return __base::size();} _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT - {return __alloc_traits::max_size(__base::__alloc());} + {return std::min( + __alloc_traits::max_size(__base::__alloc()), + numeric_limits::max());} void resize(size_type __n); void resize(size_type __n, const value_type& __v); void shrink_to_fit() _NOEXCEPT; diff --git a/include/forward_list b/include/forward_list index 41b4b468d..f344d2e1f 100644 --- a/include/forward_list +++ b/include/forward_list @@ -734,8 +734,11 @@ public: bool empty() const _NOEXCEPT {return base::__before_begin()->__next_ == nullptr;} _LIBCPP_INLINE_VISIBILITY - size_type max_size() const _NOEXCEPT - {return numeric_limits::max();} + size_type max_size() const _NOEXCEPT { + return std::min( + __node_traits::max_size(base::__alloc()), + numeric_limits::max()); + } _LIBCPP_INLINE_VISIBILITY reference front() {return base::__before_begin()->__next_->__value_;} diff --git a/include/list b/include/list index bebfff66c..98843d61f 100644 --- a/include/list +++ b/include/list @@ -570,6 +570,10 @@ protected: const __node_allocator& __node_alloc() const _NOEXCEPT {return __size_alloc_.second();} + _LIBCPP_INLINE_VISIBILITY + size_type __node_alloc_max_size() const _NOEXCEPT { + return __node_alloc_traits::max_size(__node_alloc()); + } _LIBCPP_INLINE_VISIBILITY static void __unlink_nodes(__link_pointer __f, __link_pointer __l) _NOEXCEPT; @@ -904,7 +908,11 @@ public: bool empty() const _NOEXCEPT {return base::empty();} _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT - {return numeric_limits::max();} + { + return std::min( + base::__node_alloc_max_size(), + numeric_limits::max()); + } _LIBCPP_INLINE_VISIBILITY iterator begin() _NOEXCEPT {return base::begin();} diff --git a/include/vector b/include/vector index edcb7dfab..f5bd7d072 100644 --- a/include/vector +++ b/include/vector @@ -941,7 +941,8 @@ template typename vector<_Tp, _Allocator>::size_type vector<_Tp, _Allocator>::max_size() const _NOEXCEPT { - return _VSTD::min(__alloc_traits::max_size(this->__alloc()), numeric_limits::max() / 2); // end() >= begin(), always + return _VSTD::min(__alloc_traits::max_size(this->__alloc()), + numeric_limits::max()); } // Precondition: __new_size > capacity() diff --git a/test/std/containers/associative/map/map.access/max_size.pass.cpp b/test/std/containers/associative/map/map.access/max_size.pass.cpp index c67d8b1f6..82a817a1f 100644 --- a/test/std/containers/associative/map/map.access/max_size.pass.cpp +++ b/test/std/containers/associative/map/map.access/max_size.pass.cpp @@ -13,23 +13,39 @@ // size_type max_size() const; -#include #include +#include +#include +#include -#include "min_allocator.h" +#include "test_allocator.h" +#include "test_macros.h" int main() { - { - typedef std::map M; - M m; - assert(m.max_size() != 0); + typedef std::pair KV; + { + typedef limited_allocator A; + typedef std::map, A> C; + C c; + assert(c.max_size() <= 10); + LIBCPP_ASSERT(c.max_size() == 10); + } + { + typedef limited_allocator A; + typedef std::map, A> C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + LIBCPP_ASSERT(c.max_size() == max_dist); } -#if TEST_STD_VER >= 11 { - typedef std::map, min_allocator>> M; - M m; - assert(m.max_size() != 0); + typedef std::map C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + assert(c.max_size() <= alloc_max_size(c.get_allocator())); } -#endif } diff --git a/test/std/containers/associative/multimap/max_size.pass.cpp b/test/std/containers/associative/multimap/max_size.pass.cpp index b7cf226d8..8d5ec1148 100644 --- a/test/std/containers/associative/multimap/max_size.pass.cpp +++ b/test/std/containers/associative/multimap/max_size.pass.cpp @@ -13,23 +13,39 @@ // size_type max_size() const; -#include #include +#include +#include +#include -#include "min_allocator.h" +#include "test_allocator.h" +#include "test_macros.h" int main() { - { - typedef std::multimap M; - M m; - assert(m.max_size() != 0); + typedef std::pair KV; + { + typedef limited_allocator A; + typedef std::multimap, A> C; + C c; + assert(c.max_size() <= 10); + LIBCPP_ASSERT(c.max_size() == 10); + } + { + typedef limited_allocator A; + typedef std::multimap, A> C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + LIBCPP_ASSERT(c.max_size() == max_dist); } -#if TEST_STD_VER >= 11 { - typedef std::multimap, min_allocator>> M; - M m; - assert(m.max_size() != 0); + typedef std::multimap C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + assert(c.max_size() <= alloc_max_size(c.get_allocator())); } -#endif } diff --git a/test/std/containers/associative/multiset/max_size.pass.cpp b/test/std/containers/associative/multiset/max_size.pass.cpp index 79492c9b1..8ca34ba82 100644 --- a/test/std/containers/associative/multiset/max_size.pass.cpp +++ b/test/std/containers/associative/multiset/max_size.pass.cpp @@ -13,23 +13,38 @@ // size_type max_size() const; -#include #include +#include +#include +#include -#include "min_allocator.h" +#include "test_allocator.h" +#include "test_macros.h" int main() { { - typedef std::multiset M; - M m; - assert(m.max_size() != 0); + typedef limited_allocator A; + typedef std::multiset, A> C; + C c; + assert(c.max_size() <= 10); + LIBCPP_ASSERT(c.max_size() == 10); } -#if TEST_STD_VER >= 11 { - typedef std::multiset, min_allocator> M; - M m; - assert(m.max_size() != 0); + typedef limited_allocator A; + typedef std::multiset, A> C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + LIBCPP_ASSERT(c.max_size() == max_dist); + } + { + typedef std::multiset C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + assert(c.max_size() <= alloc_max_size(c.get_allocator())); } -#endif } diff --git a/test/std/containers/associative/set/max_size.pass.cpp b/test/std/containers/associative/set/max_size.pass.cpp index 9df6a4157..c894eb51b 100644 --- a/test/std/containers/associative/set/max_size.pass.cpp +++ b/test/std/containers/associative/set/max_size.pass.cpp @@ -13,23 +13,38 @@ // size_type max_size() const; -#include #include +#include +#include +#include -#include "min_allocator.h" +#include "test_allocator.h" +#include "test_macros.h" int main() { { - typedef std::set M; - M m; - assert(m.max_size() != 0); + typedef limited_allocator A; + typedef std::set, A> C; + C c; + assert(c.max_size() <= 10); + LIBCPP_ASSERT(c.max_size() == 10); } -#if TEST_STD_VER >= 11 { - typedef std::set, min_allocator> M; - M m; - assert(m.max_size() != 0); + typedef limited_allocator A; + typedef std::set, A> C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + LIBCPP_ASSERT(c.max_size() == max_dist); + } + { + typedef std::set C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + assert(c.max_size() <= alloc_max_size(c.get_allocator())); } -#endif } diff --git a/test/std/containers/sequences/deque/deque.capacity/max_size.pass.cpp b/test/std/containers/sequences/deque/deque.capacity/max_size.pass.cpp new file mode 100644 index 000000000..11ce9d2f6 --- /dev/null +++ b/test/std/containers/sequences/deque/deque.capacity/max_size.pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type max_size() const; + +#include +#include +#include +#include + +#include "test_allocator.h" +#include "test_macros.h" + +int main() { + { + typedef limited_allocator A; + typedef std::deque C; + C c; + assert(c.max_size() <= 10); + LIBCPP_ASSERT(c.max_size() == 10); + } + { + typedef limited_allocator A; + typedef std::deque C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + LIBCPP_ASSERT(c.max_size() == max_dist); + } + { + typedef std::deque C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + assert(c.max_size() <= alloc_max_size(c.get_allocator())); + } +} diff --git a/test/std/containers/sequences/forwardlist/max_size.pass.cpp b/test/std/containers/sequences/forwardlist/max_size.pass.cpp index a7f39bf90..916d12a9f 100644 --- a/test/std/containers/sequences/forwardlist/max_size.pass.cpp +++ b/test/std/containers/sequences/forwardlist/max_size.pass.cpp @@ -11,25 +11,38 @@ // size_type max_size() const; -#include #include +#include +#include +#include -#include "min_allocator.h" +#include "test_allocator.h" +#include "test_macros.h" int main() { { - typedef int T; - typedef std::forward_list C; - C c; - assert(c.max_size() > 0); + typedef limited_allocator A; + typedef std::forward_list C; + C c; + assert(c.max_size() <= 10); + LIBCPP_ASSERT(c.max_size() == 10); } -#if TEST_STD_VER >= 11 { - typedef int T; - typedef std::forward_list> C; - C c; - assert(c.max_size() > 0); + typedef limited_allocator A; + typedef std::forward_list C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + LIBCPP_ASSERT(c.max_size() == max_dist); + } + { + typedef std::forward_list C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + assert(c.max_size() <= alloc_max_size(c.get_allocator())); } -#endif } diff --git a/test/std/containers/sequences/list/list.capacity/max_size.pass.cpp b/test/std/containers/sequences/list/list.capacity/max_size.pass.cpp new file mode 100644 index 000000000..bd1b65e63 --- /dev/null +++ b/test/std/containers/sequences/list/list.capacity/max_size.pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type max_size() const noexcept + +#include +#include +#include +#include + +#include "test_allocator.h" +#include "test_macros.h" + +int main() { + { + typedef limited_allocator A; + typedef std::list C; + C c; + assert(c.max_size() <= 10); + LIBCPP_ASSERT(c.max_size() == 10); + } + { + typedef limited_allocator A; + typedef std::list C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + LIBCPP_ASSERT(c.max_size() == max_dist); + } + { + typedef std::list C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + assert(c.max_size() <= alloc_max_size(c.get_allocator())); + } +} diff --git a/test/std/containers/sequences/vector/vector.capacity/max_size.pass.cpp b/test/std/containers/sequences/vector/vector.capacity/max_size.pass.cpp new file mode 100644 index 000000000..5f7a6268d --- /dev/null +++ b/test/std/containers/sequences/vector/vector.capacity/max_size.pass.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// size_type max_size() const; + +#include +#include +#include +#include + +#include "test_allocator.h" +#include "test_macros.h" + + +int main() { + { + typedef limited_allocator A; + typedef std::vector C; + C c; + assert(c.max_size() <= 10); + LIBCPP_ASSERT(c.max_size() == 10); + } + { + typedef limited_allocator A; + typedef std::vector C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + LIBCPP_ASSERT(c.max_size() == max_dist); + } + { + typedef std::vector C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + assert(c.max_size() <= alloc_max_size(c.get_allocator())); + } +} diff --git a/test/std/containers/unord/unord.map/max_size.pass.cpp b/test/std/containers/unord/unord.map/max_size.pass.cpp index 9c1ca18c3..152741981 100644 --- a/test/std/containers/unord/unord.map/max_size.pass.cpp +++ b/test/std/containers/unord/unord.map/max_size.pass.cpp @@ -9,28 +9,45 @@ // -// template , class Pred = equal_to, -// class Alloc = allocator>> // class unordered_map // size_type max_size() const; -#include #include +#include +#include +#include -#include "min_allocator.h" +#include "test_allocator.h" +#include "test_macros.h" int main() { - { - std::unordered_map u; - assert(u.max_size() > 0); + typedef std::pair KV; + { + typedef limited_allocator A; + typedef std::unordered_map, std::equal_to, A> + C; + C c; + assert(c.max_size() <= 10); + LIBCPP_ASSERT(c.max_size() == 10); + } + { + typedef limited_allocator A; + typedef std::unordered_map, std::equal_to, A> + C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + LIBCPP_ASSERT(c.max_size() == max_dist); } -#if TEST_STD_VER >= 11 { - std::unordered_map, std::equal_to, - min_allocator>> u; - assert(u.max_size() > 0); + typedef std::unordered_map C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + assert(c.max_size() <= alloc_max_size(c.get_allocator())); } -#endif } diff --git a/test/std/containers/unord/unord.multimap/max_size.pass.cpp b/test/std/containers/unord/unord.multimap/max_size.pass.cpp index 3bf1f1496..5b58bac38 100644 --- a/test/std/containers/unord/unord.multimap/max_size.pass.cpp +++ b/test/std/containers/unord/unord.multimap/max_size.pass.cpp @@ -9,28 +9,47 @@ // -// template , class Pred = equal_to, -// class Alloc = allocator>> // class unordered_multimap // size_type max_size() const; -#include #include +#include +#include +#include -#include "min_allocator.h" +#include "test_allocator.h" +#include "test_macros.h" int main() { - { - std::unordered_multimap u; - assert(u.max_size() > 0); + typedef std::pair KV; + { + typedef limited_allocator A; + typedef std::unordered_multimap, + std::equal_to, A> + C; + C c; + assert(c.max_size() <= 10); + LIBCPP_ASSERT(c.max_size() == 10); + } + { + typedef limited_allocator A; + typedef std::unordered_multimap, + std::equal_to, A> + C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + LIBCPP_ASSERT(c.max_size() == max_dist); } -#if TEST_STD_VER >= 11 { - std::unordered_multimap, std::equal_to, - min_allocator>> u; - assert(u.max_size() > 0); + typedef std::unordered_multimap C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + assert(c.max_size() <= alloc_max_size(c.get_allocator())); } -#endif } diff --git a/test/std/containers/unord/unord.multiset/max_size.pass.cpp b/test/std/containers/unord/unord.multiset/max_size.pass.cpp index b26ad73fe..eac4db8b0 100644 --- a/test/std/containers/unord/unord.multiset/max_size.pass.cpp +++ b/test/std/containers/unord/unord.multiset/max_size.pass.cpp @@ -9,28 +9,46 @@ // -// template , class Pred = equal_to, -// class Alloc = allocator> // class unordered_multiset // size_type max_size() const; -#include #include +#include +#include +#include -#include "min_allocator.h" +#include "test_allocator.h" +#include "test_macros.h" int main() { { - std::unordered_multiset u; - assert(u.max_size() > 0); + typedef limited_allocator A; + typedef std::unordered_multiset, std::equal_to, + A> + C; + C c; + assert(c.max_size() <= 10); + LIBCPP_ASSERT(c.max_size() == 10); } -#if TEST_STD_VER >= 11 { - std::unordered_multiset, - std::equal_to, min_allocator> u; - assert(u.max_size() > 0); + typedef limited_allocator A; + typedef std::unordered_multiset, std::equal_to, + A> + C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + LIBCPP_ASSERT(c.max_size() == max_dist); + } + { + typedef std::unordered_multiset C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + assert(c.max_size() <= alloc_max_size(c.get_allocator())); } -#endif } diff --git a/test/std/containers/unord/unord.set/max_size.pass.cpp b/test/std/containers/unord/unord.set/max_size.pass.cpp index 3135ad994..1b902660d 100644 --- a/test/std/containers/unord/unord.set/max_size.pass.cpp +++ b/test/std/containers/unord/unord.set/max_size.pass.cpp @@ -9,28 +9,42 @@ // -// template , class Pred = equal_to, -// class Alloc = allocator> // class unordered_set // size_type max_size() const; -#include #include +#include +#include +#include -#include "min_allocator.h" +#include "test_allocator.h" +#include "test_macros.h" int main() { { - std::unordered_set u; - assert(u.max_size() > 0); + typedef limited_allocator A; + typedef std::unordered_set, std::equal_to, A> C; + C c; + assert(c.max_size() <= 10); + LIBCPP_ASSERT(c.max_size() == 10); } -#if TEST_STD_VER >= 11 { - std::unordered_set, - std::equal_to, min_allocator> u; - assert(u.max_size() > 0); + typedef limited_allocator A; + typedef std::unordered_set, std::equal_to, A> C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + LIBCPP_ASSERT(c.max_size() == max_dist); + } + { + typedef std::unordered_set C; + const C::difference_type max_dist = + std::numeric_limits::max(); + C c; + assert(c.max_size() <= max_dist); + assert(c.max_size() <= alloc_max_size(c.get_allocator())); } -#endif } diff --git a/test/support/test_allocator.h b/test/support/test_allocator.h index 4e93ca5a9..7ce60025f 100644 --- a/test/support/test_allocator.h +++ b/test/support/test_allocator.h @@ -20,6 +20,12 @@ #include "test_macros.h" +template +inline size_t alloc_max_size(Alloc const &a) { + typedef std::allocator_traits AT; + return AT::max_size(a); +} + class test_alloc_base { protected: