[PATCH] D42344: [libc++] Use multi-key tree search for {map, set}::{count, equal_range}

2018-02-09 Thread N via Phabricator via cfe-commits
ng added a comment.

Could you please commit this on my behalf? I don't have commit access.


https://reviews.llvm.org/D42344



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D42344: [libc++] Use multi-key tree search for {map, set}::{count, equal_range}

2018-01-20 Thread N via Phabricator via cfe-commits
ng created this revision.
ng added a reviewer: mclow.lists.
Herald added a reviewer: EricWF.

As described in http://bugs.llvm.org/show_bug.cgi?id=30959, the current 
implementation of std::{map, key}::{count, equal_range} in libcxx is 
non-conforming. Quoting ISO/IEC 14882:2014 section 23.2.4:

> 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.


Repository:
  rCXX libc++

https://reviews.llvm.org/D42344

Files:
  include/map
  include/set


Index: include/map
===
--- include/map
+++ include/map
@@ -1223,12 +1223,12 @@
 
 _LIBCPP_INLINE_VISIBILITY
 size_type  count(const key_type& __k) const
-{return __tree_.__count_unique(__k);}
+{return __tree_.__count_multi(__k);}
 #if _LIBCPP_STD_VER > 11
 template 
 _LIBCPP_INLINE_VISIBILITY
 typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type
-count(const _K2& __k) const {return __tree_.__count_unique(__k);}
+count(const _K2& __k) const {return __tree_.__count_multi(__k);}
 #endif
 _LIBCPP_INLINE_VISIBILITY
 iterator lower_bound(const key_type& __k)
@@ -1267,19 +1267,19 @@
 
 _LIBCPP_INLINE_VISIBILITY
 pair equal_range(const key_type& __k)
-{return __tree_.__equal_range_unique(__k);}
+{return __tree_.__equal_range_multi(__k);}
 _LIBCPP_INLINE_VISIBILITY
 pair equal_range(const key_type& __k) const
-{return __tree_.__equal_range_unique(__k);}
+{return __tree_.__equal_range_multi(__k);}
 #if _LIBCPP_STD_VER > 11
 template 
 _LIBCPP_INLINE_VISIBILITY
 typename enable_if<__is_transparent<_Compare, 
_K2>::value,pair>::type
-equal_range(const _K2& __k)   {return 
__tree_.__equal_range_unique(__k);}
+equal_range(const _K2& __k)   {return 
__tree_.__equal_range_multi(__k);}
 template 
 _LIBCPP_INLINE_VISIBILITY
 typename enable_if<__is_transparent<_Compare, 
_K2>::value,pair>::type
-equal_range(const _K2& __k) const {return 
__tree_.__equal_range_unique(__k);}
+equal_range(const _K2& __k) const {return 
__tree_.__equal_range_multi(__k);}
 #endif
 
 private:
Index: include/set
===
--- include/set
+++ include/set
@@ -663,12 +663,12 @@
 
 _LIBCPP_INLINE_VISIBILITY
 size_type  count(const key_type& __k) const
-{return __tree_.__count_unique(__k);}
+{return __tree_.__count_multi(__k);}
 #if _LIBCPP_STD_VER > 11
 template 
 _LIBCPP_INLINE_VISIBILITY
 typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type
-count(const _K2& __k) const{return 
__tree_.__count_unique(__k);}
+count(const _K2& __k) const{return 
__tree_.__count_multi(__k);}
 #endif
 _LIBCPP_INLINE_VISIBILITY
 iterator lower_bound(const key_type& __k)
@@ -707,19 +707,19 @@
 
 _LIBCPP_INLINE_VISIBILITY
 pair equal_range(const key_type& __k)
-{return __tree_.__equal_range_unique(__k);}
+{return __tree_.__equal_range_multi(__k);}
 _LIBCPP_INLINE_VISIBILITY
 pair equal_range(const key_type& __k) const
-{return __tree_.__equal_range_unique(__k);}
+{return __tree_.__equal_range_multi(__k);}
 #if _LIBCPP_STD_VER > 11
 template 
 _LIBCPP_INLINE_VISIBILITY
 typename enable_if<__is_transparent<_Compare, 
_K2>::value,pair>::type
-equal_range(const _K2& __k)   {return 
__tree_.__equal_range_unique(__k);}
+equal_range(const _K2& __k)   {return 
__tree_.__equal_range_multi(__k);}
 template 
 _LIBCPP_INLINE_VISIBILITY
 typename enable_if<__is_transparent<_Compare, 
_K2>::value,pair>::type
-equal_range(const _K2& __k) const {return 
__tree_.__equal_range_unique(__k);}
+equal_range(const _K2& __k) const {return 
__tree_.__equal_range_multi(__k);}
 #endif
 };
 


Index: include/map
===
--- include/map
+++ include/map
@@ -1223,12 +1223,12 @@
 
 _LIBCPP_INLINE_VISIBILITY
 size_type  count(const key_type& __k) const
-{return __tree_.__count_unique(__k);}
+{return __tree_.__count_multi(__k);}
 #if _LIBCPP_STD_VER > 11
 template 
 _LIBCPP_INLINE_VISIBILITY
 typename enable_if<__is_transparent<_Compare, _K2>::value,size_type>::type
-count(const _K2& __k) const {return __tree_.__count_unique(__k);}
+

[PATCH] D42344: [libc++] Use multi-key tree search for {map, set}::{count, equal_range}

2018-01-21 Thread N via Phabricator via cfe-commits
ng updated this revision to Diff 130812.
ng added a comment.

As per the above suggestions, enabled _multi tree search only for transparent 
comparator functions, and added tests.


https://reviews.llvm.org/D42344

Files:
  libcxx/include/map  
  libcxx/include/set  
  libcxx/test/std/containers/associative/map/map.ops/transparent_count.pass.cpp 
  
  
libcxx/test/std/containers/associative/map/map.ops/transparent_equal_range.pass.cpp
  
  libcxx/test/std/containers/associative/set/transparent_count.pass.cpp 
  libcxx/test/std/containers/associative/set/transparent_equal_range.pass.cpp

Index: libcxx/test/std/containers/associative/set/transparent_equal_range.pass.cpp
===
--- libcxx/test/std/containers/associative/set/transparent_equal_range.pass.cpp
+++ libcxx/test/std/containers/associative/set/transparent_equal_range.pass.cpp
@@ -0,0 +1,63 @@
+//===--===//
+//
+// 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.
+//
+//===--===//
+
+// 
+
+// class set
+
+// template
+// pair equal_range(const K& x);//
+// C++14
+// template
+// pair equal_range(const K& x) const;  //
+// C++14
+
+#include 
+#include 
+#include 
+
+#include "min_allocator.h"
+#include "private_constructor.hpp"
+#include "test_macros.h"
+
+#if TEST_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+struct Comp {
+  using is_transparent = void;
+
+  bool operator()(const std::pair &lhs,
+  const std::pair &rhs) const {
+return lhs < rhs;
+  }
+
+  bool operator()(const std::pair &lhs, int rhs) const {
+return lhs.first < rhs;
+  }
+
+  bool operator()(int lhs, const std::pair &rhs) const {
+return lhs < rhs.first;
+  }
+};
+
+int main() {
+  std::set, 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);
+}
+#endif
Index: libcxx/test/std/containers/associative/set/transparent_count.pass.cpp 
===
--- libcxx/test/std/containers/associative/set/transparent_count.pass.cpp 
+++ libcxx/test/std/containers/associative/set/transparent_count.pass.cpp 
@@ -0,0 +1,54 @@
+//===--===//
+//
+// 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.
+//
+//===--===//
+
+// 
+
+// class set
+
+// template
+// iterator lower_bound(const K& x);  // C++14
+// template
+// const_iterator lower_bound(const K& x) const;  // C++14
+
+#include 
+#include 
+#include 
+
+#include "min_allocator.h"
+#include "private_constructor.hpp"
+#include "test_macros.h"
+
+#if TEST_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+struct Comp {
+  using is_transparent = void;
+
+  bool operator()(const std::pair &lhs,
+  const std::pair &rhs) const {
+return lhs < rhs;
+  }
+
+  bool operator()(const std::pair &lhs, int rhs) const {
+return lhs.first < rhs;
+  }
+
+  bool operator()(int lhs, const std::pair &rhs) const {
+return lhs < rhs.first;
+  }
+};
+
+int main() {
+  std::set, Comp> s{{2, 1}, {1, 2}, {1, 3}, {1, 4}, {2, 2}};
+
+  auto cnt = s.count(1);
+  assert(cnt == 3);
+}
+#endif
Index: libcxx/test/std/containers/associative/map/map.ops/transparent_equal_range.pass.cpp  
===
--- libcxx/test/std/containers/associative/map/map.ops/transparent_equal_range.pass.cpp  
+++ libcxx/test/std/containers/associative/map/map.ops/transparent_equal_range.pass.cpp  
@@ -0,0 +1,63 @@
+//===--===//
+//
+// 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.
+//
+//===--===//
+
+// 
+
+// class map
+
+// template
+// pair equal_range(const K& x); // C++14
+// template
+// pair equal_range(const K& x) const;
+// // C++14
+
+#include 
+#include 
+#include 
+
+#include "min_allocator.h"
+#include "private_constructor.hpp"
+#include "test_macros.h"
+
+#if TEST_STD_VER <= 11
+#error "This test requires is C++14 (or later)"
+#else
+
+struct Co

[PATCH] D42344: [libc++] Use multi-key tree search for {map, set}::{count, equal_range}

2018-01-21 Thread N via Phabricator via cfe-commits
ng added a comment.

In https://reviews.llvm.org/D42344#983264, @mclow.lists wrote:

> Shouldn't there be tests for `multimap` and `multiset`, too?


Sure; will the same tests as for map/set be alright?


https://reviews.llvm.org/D42344



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D42344: [libc++] Use multi-key tree search for {map, set}::{count, equal_range}

2018-01-21 Thread N via Phabricator via cfe-commits
ng updated this revision to Diff 130814.
ng added a comment.

Renamed tests for map/set, and added multimap/multiset tests


https://reviews.llvm.org/D42344

Files:
  libcxx/include/map 
  libcxx/include/set 
  libcxx/test/std/containers/associative/map/map.ops/count_transparent.pass.cpp
  
libcxx/test/std/containers/associative/map/map.ops/equal_range_transparent.pass.cpp
  
libcxx/test/std/containers/associative/multimap/multimap.ops/count_transparent.pass.cpp
  
libcxx/test/std/containers/associative/multimap/multimap.ops/equal_range_transparent.pass.cpp
  libcxx/test/std/containers/associative/multiset/count_transparent.pass.cpp
  
libcxx/test/std/containers/associative/multiset/equal_range_transparent.pass.cpp
  libcxx/test/std/containers/associative/set/count_transparent.pass.cpp
  libcxx/test/std/containers/associative/set/equal_range_transparent.pass.cpp

Index: libcxx/test/std/containers/associative/set/equal_range_transparent.pass.cpp
===
--- libcxx/test/std/containers/associative/set/equal_range_transparent.pass.cpp
+++ 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
+
+// 
+
+// class set
+
+// template
+// pair equal_range(const K& x);//
+// C++14
+// template
+// pair equal_range(const K& x) const;  //
+// C++14
+
+#include 
+#include 
+#include 
+
+#include "min_allocator.h"
+#include "private_constructor.hpp"
+#include "test_macros.h"
+
+struct Comp {
+  using is_transparent = void;
+
+  bool operator()(const std::pair &lhs,
+  const std::pair &rhs) const {
+return lhs < rhs;
+  }
+
+  bool operator()(const std::pair &lhs, int rhs) const {
+return lhs.first < rhs;
+  }
+
+  bool operator()(int lhs, const std::pair &rhs) const {
+return lhs < rhs.first;
+  }
+};
+
+int main() {
+  std::set, 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);
+}
Index: libcxx/test/std/containers/associative/set/count_transparent.pass.cpp
===
--- libcxx/test/std/containers/associative/set/count_transparent.pass.cpp
+++ 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
+
+// 
+
+// class set
+
+// template
+// iterator lower_bound(const K& x);  // C++14
+// template
+// const_iterator lower_bound(const K& x) const;  // C++14
+
+#include 
+#include 
+#include 
+
+#include "min_allocator.h"
+#include "private_constructor.hpp"
+#include "test_macros.h"
+
+struct Comp {
+  using is_transparent = void;
+
+  bool operator()(const std::pair &lhs,
+  const std::pair &rhs) const {
+return lhs < rhs;
+  }
+
+  bool operator()(const std::pair &lhs, int rhs) const {
+return lhs.first < rhs;
+  }
+
+  bool operator()(int lhs, const std::pair &rhs) const {
+return lhs < rhs.first;
+  }
+};
+
+int main() {
+  std::set, Comp> s{{2, 1}, {1, 2}, {1, 3}, {1, 4}, {2, 2}};
+
+  auto cnt = s.count(1);
+  assert(cnt == 3);
+}
Index: libcxx/test/std/containers/associative/multiset/equal_range_transparent.pass.cpp
===
--- libcxx/test/std/containers/associative/multiset/equal_range_transparent.pass.cpp
+++ libcxx/test/std/containers/associative/multiset/equal_range_transparent.pass.cpp
@@ -0,0 +1,61 @@
+//===--===//
+//
+// 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
+
+// 
+
+// class multiset
+
+// template
+// pair equal_range(const K& x);//
+// C++14
+// template
+// pair equal_range(const K& x) const;  //
+// C++14
+
+#include

[PATCH] D42344: [libc++] Use multi-key tree search for {map, set}::{count, equal_range}

2018-01-21 Thread N via Phabricator via cfe-commits
ng updated this revision to Diff 130817.
ng added a comment.

Fix multiset variable definition in tests


https://reviews.llvm.org/D42344

Files:
  libcxx/include/map 
  libcxx/include/set 
  libcxx/test/std/containers/associative/map/map.ops/count_transparent.pass.cpp
  
libcxx/test/std/containers/associative/map/map.ops/equal_range_transparent.pass.cpp
  
libcxx/test/std/containers/associative/multimap/multimap.ops/count_transparent.pass.cpp
  
libcxx/test/std/containers/associative/multimap/multimap.ops/equal_range_transparent.pass.cpp
  libcxx/test/std/containers/associative/multiset/count_transparent.pass.cpp
  
libcxx/test/std/containers/associative/multiset/equal_range_transparent.pass.cpp
  libcxx/test/std/containers/associative/set/count_transparent.pass.cpp
  libcxx/test/std/containers/associative/set/equal_range_transparent.pass.cpp

Index: libcxx/test/std/containers/associative/set/equal_range_transparent.pass.cpp
===
--- libcxx/test/std/containers/associative/set/equal_range_transparent.pass.cpp
+++ 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
+
+// 
+
+// class set
+
+// template
+// pair equal_range(const K& x);//
+// C++14
+// template
+// pair equal_range(const K& x) const;  //
+// C++14
+
+#include 
+#include 
+#include 
+
+#include "min_allocator.h"
+#include "private_constructor.hpp"
+#include "test_macros.h"
+
+struct Comp {
+  using is_transparent = void;
+
+  bool operator()(const std::pair &lhs,
+  const std::pair &rhs) const {
+return lhs < rhs;
+  }
+
+  bool operator()(const std::pair &lhs, int rhs) const {
+return lhs.first < rhs;
+  }
+
+  bool operator()(int lhs, const std::pair &rhs) const {
+return lhs < rhs.first;
+  }
+};
+
+int main() {
+  std::set, 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);
+}
Index: libcxx/test/std/containers/associative/set/count_transparent.pass.cpp
===
--- libcxx/test/std/containers/associative/set/count_transparent.pass.cpp
+++ 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
+
+// 
+
+// class set
+
+// template
+// iterator lower_bound(const K& x);  // C++14
+// template
+// const_iterator lower_bound(const K& x) const;  // C++14
+
+#include 
+#include 
+#include 
+
+#include "min_allocator.h"
+#include "private_constructor.hpp"
+#include "test_macros.h"
+
+struct Comp {
+  using is_transparent = void;
+
+  bool operator()(const std::pair &lhs,
+  const std::pair &rhs) const {
+return lhs < rhs;
+  }
+
+  bool operator()(const std::pair &lhs, int rhs) const {
+return lhs.first < rhs;
+  }
+
+  bool operator()(int lhs, const std::pair &rhs) const {
+return lhs < rhs.first;
+  }
+};
+
+int main() {
+  std::set, Comp> s{{2, 1}, {1, 2}, {1, 3}, {1, 4}, {2, 2}};
+
+  auto cnt = s.count(1);
+  assert(cnt == 3);
+}
Index: libcxx/test/std/containers/associative/multiset/equal_range_transparent.pass.cpp
===
--- libcxx/test/std/containers/associative/multiset/equal_range_transparent.pass.cpp
+++ 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
+
+// 
+
+// class multiset
+
+// template
+// pair equal_range(const K& x);//
+// C++14
+// template
+// pair equal_range(const K& x) const;  //
+// C++14
+
+#include 
+#include 
+#incl

[PATCH] D42344: [libc++] Use multi-key tree search for {map, set}::{count, equal_range}

2018-01-25 Thread N via Phabricator via cfe-commits
ng added a comment.

Ping


https://reviews.llvm.org/D42344



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits