[libcxx-commits] [libcxx] [libc++] Add positive test coverage for the string optimization on associative containers (PR #187345)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Mar 26 11:48:32 PDT 2026
https://github.com/ldionne updated https://github.com/llvm/llvm-project/pull/187345
>From cb0bd0ad5928d91103023f4d71db077cb9ce8186 Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Wed, 18 Mar 2026 14:19:47 -0400
Subject: [PATCH] [libc++] Add positive test coverage for the string
optimization on associative containers
Unfortunately, this test needs to be somewhat tied to the fact that we
implement the optimization for std::string, but in practice it would have
caught the issue that the optimization was previously disabled, so it
does provide value.
Towards #187105
---
...kup_with_transparently_comparable.pass.cpp | 144 ++++++++++++++++++
1 file changed, 144 insertions(+)
create mode 100644 libcxx/test/libcxx/containers/associative/lookup_with_transparently_comparable.pass.cpp
diff --git a/libcxx/test/libcxx/containers/associative/lookup_with_transparently_comparable.pass.cpp b/libcxx/test/libcxx/containers/associative/lookup_with_transparently_comparable.pass.cpp
new file mode 100644
index 0000000000000..219df94168b55
--- /dev/null
+++ b/libcxx/test/libcxx/containers/associative/lookup_with_transparently_comparable.pass.cpp
@@ -0,0 +1,144 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11
+
+// Make sure that lookup operations on ordered associative containers are transparent
+// when they can, even when not using a comparator that advertises itself as transparent
+// (e.g. std::less<>). This is a libc++ QoI extension.
+//
+// At the moment, we only implement this optimization when the key stored in the container
+// is std::string, so the tests are written with that assumption in mind.
+
+#include <cassert>
+#include <functional>
+#include <map>
+#include <set>
+#include <string>
+
+#include "count_new.h"
+#include "test_macros.h"
+
+template <class Container>
+void test() {
+ // Use a string longer than the SSO so that construction must allocate.
+ const char* key = "long-string-to-exceed-SSO-buffer";
+
+ // find
+ {
+ Container c;
+ globalMemCounter.reset();
+ (void)c.find(key);
+ assert(globalMemCounter.checkNewCalledEq(0));
+ }
+ {
+ Container const c;
+ globalMemCounter.reset();
+ (void)c.find(key);
+ assert(globalMemCounter.checkNewCalledEq(0));
+ }
+
+ // count -- TODO: implement the optimization
+ // {
+ // globalMemCounter.reset();
+ // (void)c.count(key);
+ // assert(globalMemCounter.checkNewCalledEq(0));
+ // }
+
+#if TEST_STD_VER >= 20
+ // contains
+ {
+ Container c;
+ globalMemCounter.reset();
+ (void)c.contains(key);
+ assert(globalMemCounter.checkNewCalledEq(0));
+ }
+ {
+ Container const c;
+ globalMemCounter.reset();
+ (void)c.contains(key);
+ assert(globalMemCounter.checkNewCalledEq(0));
+ }
+#endif
+
+ // TODO: Implement the optimization for these methods
+ // lower_bound
+ // {
+ // Container c;
+ // globalMemCounter.reset();
+ // (void)c.lower_bound(key);
+ // assert(globalMemCounter.checkNewCalledEq(0));
+ // }
+ // {
+ // Container const c;
+ // globalMemCounter.reset();
+ // (void)c.lower_bound(key);
+ // assert(globalMemCounter.checkNewCalledEq(0));
+ // }
+
+ // upper_bound
+ // {
+ // Container c;
+ // globalMemCounter.reset();
+ // (void)c.upper_bound(key);
+ // assert(globalMemCounter.checkNewCalledEq(0));
+ // }
+ // {
+ // Container const c;
+ // globalMemCounter.reset();
+ // (void)c.upper_bound(key);
+ // assert(globalMemCounter.checkNewCalledEq(0));
+ // }
+
+ // equal_range
+ // {
+ // Container c;
+ // globalMemCounter.reset();
+ // (void)c.equal_range(key);
+ // assert(globalMemCounter.checkNewCalledEq(0));
+ // }
+ // {
+ // Container const c;
+ // globalMemCounter.reset();
+ // (void)c.equal_range(key);
+ // assert(globalMemCounter.checkNewCalledEq(0));
+ // }
+}
+
+int main(int, char**) {
+ test<std::map<std::string, int>>();
+ // TODO: Implement the optimization for multimap, set and multiset
+ // test<std::multimap<std::string, int>>();
+ // test<std::set<std::string>>();
+ // test<std::multiset<std::string>>();
+
+ test<std::map<std::string, int, std::greater<std::string>>>();
+ // test<std::multimap<std::string, int, std::greater<std::string>>>();
+ // test<std::set<std::string, std::greater<std::string>>>();
+ // test<std::multiset<std::string, std::greater<std::string>>>();
+
+ {
+ // std::map only: map::at
+ std::map<std::string, int> c;
+ char const* key = "long-string-to-exceed-SSO-buffer";
+ c[key] = 1;
+ {
+ globalMemCounter.reset();
+ (void)c.at(key);
+ assert(globalMemCounter.checkNewCalledEq(0));
+ }
+ {
+ const std::map<std::string, int>& cc = c;
+ globalMemCounter.reset();
+ (void)cc.at(key);
+ assert(globalMemCounter.checkNewCalledEq(0));
+ }
+ }
+
+ return 0;
+}
More information about the libcxx-commits
mailing list