diff options
| author | Eric Fiselier <eric@efcs.ca> | 2018-02-10 02:53:47 +0000 |
|---|---|---|
| committer | Eric Fiselier <eric@efcs.ca> | 2018-02-10 02:53:47 +0000 |
| commit | 9bfdb770cc7f513546468e9a4867fa9fdce6caaf (patch) | |
| tree | 51523eb1332d36ad75733f471d2708be267ba386 /libcxx/test/std | |
| parent | 08225bbed4a26b953b9e43b66cf1f6756917c9c4 (diff) | |
| download | bcm5719-llvm-9bfdb770cc7f513546468e9a4867fa9fdce6caaf.tar.gz bcm5719-llvm-9bfdb770cc7f513546468e9a4867fa9fdce6caaf.zip | |
Use multi-key tree search for {map, set}::{count, equal_range}
Patch from ngolovliov@gmail.com
Reviewed as: https://reviews.llvm.org/D42344
As described in llvm.org/PR30959, the current
implementation of std::{map, key}::{count, equal_range} in libcxx is
non-conforming. Quoting the C++14 standard [associative.reqmts]p3
> The phrase “equivalence of keys” means the equivalence relation imposed by
> the comparison and not the operator== on keys. That is, two keys k1 and k2 are
> considered to be equivalent if for the comparison object comp,
> comp(k1, k2) == false && comp(k2, k1) == false.
In the same section, the requirements table states the following:
> a.equal_range(k) equivalent to make_pair(a.lower_bound(k), a.upper_bound(k))
> a.count(k) returns the number of elements with key equivalent to k
The behaviour of libstdc++ seems to conform to the standard here.
llvm-svn: 324799
Diffstat (limited to 'libcxx/test/std')
8 files changed, 442 insertions, 0 deletions
diff --git a/libcxx/test/std/containers/associative/map/map.ops/count_transparent.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/count_transparent.pass.cpp new file mode 100644 index 00000000000..899757e54c4 --- /dev/null +++ b/libcxx/test/std/containers/associative/map/map.ops/count_transparent.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <map> + +// class map + +// template<typename K> +// size_type count(const K& x) const; // C++14 + +#include <cassert> +#include <map> +#include <utility> + +#include "min_allocator.h" +#include "private_constructor.hpp" +#include "test_macros.h" + +struct Comp { + using is_transparent = void; + + bool operator()(const std::pair<int, int> &lhs, + const std::pair<int, int> &rhs) const { + return lhs < rhs; + } + + bool operator()(const std::pair<int, int> &lhs, int rhs) const { + return lhs.first < rhs; + } + + bool operator()(int lhs, const std::pair<int, int> &rhs) const { + return lhs < rhs.first; + } +}; + +int main() { + std::map<std::pair<int, int>, int, Comp> s{ + {{2, 1}, 1}, {{1, 2}, 2}, {{1, 3}, 3}, {{1, 4}, 4}, {{2, 2}, 5}}; + + auto cnt = s.count(1); + assert(cnt == 3); +} diff --git a/libcxx/test/std/containers/associative/map/map.ops/equal_range_transparent.pass.cpp b/libcxx/test/std/containers/associative/map/map.ops/equal_range_transparent.pass.cpp new file mode 100644 index 00000000000..cce90c69572 --- /dev/null +++ b/libcxx/test/std/containers/associative/map/map.ops/equal_range_transparent.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <map> + +// class map + +// template<typename K> +// pair<iterator,iterator> equal_range(const K& x); // C++14 +// template<typename K> +// pair<const_iterator,const_iterator> equal_range(const K& x) const; +// // C++14 + +#include <cassert> +#include <map> +#include <utility> + +#include "min_allocator.h" +#include "private_constructor.hpp" +#include "test_macros.h" + +struct Comp { + using is_transparent = void; + + bool operator()(const std::pair<int, int> &lhs, + const std::pair<int, int> &rhs) const { + return lhs < rhs; + } + + bool operator()(const std::pair<int, int> &lhs, int rhs) const { + return lhs.first < rhs; + } + + bool operator()(int lhs, const std::pair<int, int> &rhs) const { + return lhs < rhs.first; + } +}; + +int main() { + std::map<std::pair<int, int>, int, Comp> s{ + {{2, 1}, 1}, {{1, 2}, 2}, {{1, 3}, 3}, {{1, 4}, 4}, {{2, 2}, 5}}; + + auto er = s.equal_range(1); + long nels = 0; + + for (auto it = er.first; it != er.second; it++) { + assert(it->first.first == 1); + nels++; + } + + assert(nels == 3); +} diff --git a/libcxx/test/std/containers/associative/multimap/multimap.ops/count_transparent.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.ops/count_transparent.pass.cpp new file mode 100644 index 00000000000..a1dbf806a30 --- /dev/null +++ b/libcxx/test/std/containers/associative/multimap/multimap.ops/count_transparent.pass.cpp @@ -0,0 +1,50 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <map> + +// class multimap + +// template<typename K> +// size_type count(const K& x) const; // C++14 + +#include <cassert> +#include <map> +#include <utility> + +#include "min_allocator.h" +#include "private_constructor.hpp" +#include "test_macros.h" + +struct Comp { + using is_transparent = void; + + bool operator()(const std::pair<int, int> &lhs, + const std::pair<int, int> &rhs) const { + return lhs < rhs; + } + + bool operator()(const std::pair<int, int> &lhs, int rhs) const { + return lhs.first < rhs; + } + + bool operator()(int lhs, const std::pair<int, int> &rhs) const { + return lhs < rhs.first; + } +}; + +int main() { + std::multimap<std::pair<int, int>, int, Comp> s{ + {{2, 1}, 1}, {{1, 1}, 2}, {{1, 1}, 3}, {{1, 1}, 4}, {{2, 2}, 5}}; + + auto cnt = s.count(1); + assert(cnt == 3); +} diff --git a/libcxx/test/std/containers/associative/multimap/multimap.ops/equal_range_transparent.pass.cpp b/libcxx/test/std/containers/associative/multimap/multimap.ops/equal_range_transparent.pass.cpp new file mode 100644 index 00000000000..2b199d23c29 --- /dev/null +++ b/libcxx/test/std/containers/associative/multimap/multimap.ops/equal_range_transparent.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <map> + +// class multimap + +// template<typename K> +// pair<iterator,iterator> equal_range(const K& x); // C++14 +// template<typename K> +// pair<const_iterator,const_iterator> equal_range(const K& x) const; +// // C++14 + +#include <cassert> +#include <map> +#include <utility> + +#include "min_allocator.h" +#include "private_constructor.hpp" +#include "test_macros.h" + +struct Comp { + using is_transparent = void; + + bool operator()(const std::pair<int, int> &lhs, + const std::pair<int, int> &rhs) const { + return lhs < rhs; + } + + bool operator()(const std::pair<int, int> &lhs, int rhs) const { + return lhs.first < rhs; + } + + bool operator()(int lhs, const std::pair<int, int> &rhs) const { + return lhs < rhs.first; + } +}; + +int main() { + std::multimap<std::pair<int, int>, int, Comp> s{ + {{2, 1}, 1}, {{1, 1}, 2}, {{1, 1}, 3}, {{1, 1}, 4}, {{2, 2}, 5}}; + + auto er = s.equal_range(1); + long nels = 0; + + for (auto it = er.first; it != er.second; it++) { + assert(it->first.first == 1); + nels++; + } + + assert(nels == 3); +} diff --git a/libcxx/test/std/containers/associative/multiset/count_transparent.pass.cpp b/libcxx/test/std/containers/associative/multiset/count_transparent.pass.cpp new file mode 100644 index 00000000000..9ef22334586 --- /dev/null +++ b/libcxx/test/std/containers/associative/multiset/count_transparent.pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <set> + +// class multiset + +// template<typename K> +// iterator lower_bound(const K& x); // C++14 +// template<typename K> +// const_iterator lower_bound(const K& x) const; // C++14 + +#include <cassert> +#include <set> +#include <utility> + +#include "min_allocator.h" +#include "private_constructor.hpp" +#include "test_macros.h" + +struct Comp { + using is_transparent = void; + + bool operator()(const std::pair<int, int> &lhs, + const std::pair<int, int> &rhs) const { + return lhs < rhs; + } + + bool operator()(const std::pair<int, int> &lhs, int rhs) const { + return lhs.first < rhs; + } + + bool operator()(int lhs, const std::pair<int, int> &rhs) const { + return lhs < rhs.first; + } +}; + +int main() { + std::multiset<std::pair<int, int>, Comp> s{{2, 1}, {1, 1}, {1, 1}, {1, 1}, {2, 2}}; + + auto cnt = s.count(1); + assert(cnt == 3); +} diff --git a/libcxx/test/std/containers/associative/multiset/equal_range_transparent.pass.cpp b/libcxx/test/std/containers/associative/multiset/equal_range_transparent.pass.cpp new file mode 100644 index 00000000000..ffd87acfd32 --- /dev/null +++ b/libcxx/test/std/containers/associative/multiset/equal_range_transparent.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <set> + +// class multiset + +// template<typename K> +// pair<iterator,iterator> equal_range(const K& x); // +// C++14 +// template<typename K> +// pair<const_iterator,const_iterator> equal_range(const K& x) const; // +// C++14 + +#include <cassert> +#include <set> +#include <utility> + +#include "min_allocator.h" +#include "private_constructor.hpp" +#include "test_macros.h" + +struct Comp { + using is_transparent = void; + + bool operator()(const std::pair<int, int> &lhs, + const std::pair<int, int> &rhs) const { + return lhs < rhs; + } + + bool operator()(const std::pair<int, int> &lhs, int rhs) const { + return lhs.first < rhs; + } + + bool operator()(int lhs, const std::pair<int, int> &rhs) const { + return lhs < rhs.first; + } +}; + +int main() { + std::multiset<std::pair<int, int>, Comp> s{{2, 1}, {1, 1}, {1, 1}, {1, 1}, {2, 2}}; + + auto er = s.equal_range(1); + long nels = 0; + + for (auto it = er.first; it != er.second; it++) { + assert(it->first == 1); + nels++; + } + + assert(nels == 3); +} diff --git a/libcxx/test/std/containers/associative/set/count_transparent.pass.cpp b/libcxx/test/std/containers/associative/set/count_transparent.pass.cpp new file mode 100644 index 00000000000..26908eacd23 --- /dev/null +++ b/libcxx/test/std/containers/associative/set/count_transparent.pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <set> + +// class set + +// template<typename K> +// iterator lower_bound(const K& x); // C++14 +// template<typename K> +// const_iterator lower_bound(const K& x) const; // C++14 + +#include <cassert> +#include <set> +#include <utility> + +#include "min_allocator.h" +#include "private_constructor.hpp" +#include "test_macros.h" + +struct Comp { + using is_transparent = void; + + bool operator()(const std::pair<int, int> &lhs, + const std::pair<int, int> &rhs) const { + return lhs < rhs; + } + + bool operator()(const std::pair<int, int> &lhs, int rhs) const { + return lhs.first < rhs; + } + + bool operator()(int lhs, const std::pair<int, int> &rhs) const { + return lhs < rhs.first; + } +}; + +int main() { + std::set<std::pair<int, int>, Comp> s{{2, 1}, {1, 2}, {1, 3}, {1, 4}, {2, 2}}; + + auto cnt = s.count(1); + assert(cnt == 3); +} diff --git a/libcxx/test/std/containers/associative/set/equal_range_transparent.pass.cpp b/libcxx/test/std/containers/associative/set/equal_range_transparent.pass.cpp new file mode 100644 index 00000000000..88030847abc --- /dev/null +++ b/libcxx/test/std/containers/associative/set/equal_range_transparent.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +// <set> + +// class set + +// template<typename K> +// pair<iterator,iterator> equal_range(const K& x); // +// C++14 +// template<typename K> +// pair<const_iterator,const_iterator> equal_range(const K& x) const; // +// C++14 + +#include <cassert> +#include <set> +#include <utility> + +#include "min_allocator.h" +#include "private_constructor.hpp" +#include "test_macros.h" + +struct Comp { + using is_transparent = void; + + bool operator()(const std::pair<int, int> &lhs, + const std::pair<int, int> &rhs) const { + return lhs < rhs; + } + + bool operator()(const std::pair<int, int> &lhs, int rhs) const { + return lhs.first < rhs; + } + + bool operator()(int lhs, const std::pair<int, int> &rhs) const { + return lhs < rhs.first; + } +}; + +int main() { + std::set<std::pair<int, int>, Comp> s{{2, 1}, {1, 2}, {1, 3}, {1, 4}, {2, 2}}; + + auto er = s.equal_range(1); + long nels = 0; + + for (auto it = er.first; it != er.second; it++) { + assert(it->first == 1); + nels++; + } + + assert(nels == 3); +} |

