Skip to content

[libc++] constexpr priority_queue #140634

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions libcxx/docs/FeatureTestMacroTable.rst
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,8 @@ Status
---------------------------------------------------------- -----------------
``__cpp_lib_constexpr_new`` ``202406L``
---------------------------------------------------------- -----------------
``__cpp_lib_constexpr_queue`` ``202502L``
---------------------------------------------------------- -----------------
``__cpp_lib_constrained_equality`` *unimplemented*
---------------------------------------------------------- -----------------
``__cpp_lib_copyable_function`` *unimplemented*
Expand Down
138 changes: 77 additions & 61 deletions libcxx/include/queue

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions libcxx/include/version
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ __cpp_lib_constexpr_memory 202202L <memory>
201811L // C++20
__cpp_lib_constexpr_new 202406L <new>
__cpp_lib_constexpr_numeric 201911L <numeric>
__cpp_lib_constexpr_queue 202502L <queue>
__cpp_lib_constexpr_string 201907L <string>
__cpp_lib_constexpr_string_view 201811L <string_view>
__cpp_lib_constexpr_tuple 201811L <tuple>
Expand Down Expand Up @@ -545,6 +546,7 @@ __cpp_lib_void_t 201411L <type_traits>
# if !defined(_LIBCPP_ABI_VCRUNTIME)
# define __cpp_lib_constexpr_new 202406L
# endif
# define __cpp_lib_constexpr_queue 202502L
// # define __cpp_lib_constrained_equality 202403L
// # define __cpp_lib_copyable_function 202306L
// # define __cpp_lib_debugging 202311L
Expand Down
22 changes: 12 additions & 10 deletions libcxx/test/std/containers/Emplaceable.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,39 +15,41 @@
#if TEST_STD_VER >= 11

class Emplaceable {
Emplaceable(const Emplaceable&);
Emplaceable& operator=(const Emplaceable&);
TEST_CONSTEXPR Emplaceable(const Emplaceable&);
TEST_CONSTEXPR_CXX14 Emplaceable& operator=(const Emplaceable&);

int int_;
double double_;

public:
Emplaceable() : int_(0), double_(0) {}
Emplaceable(int i, double d) : int_(i), double_(d) {}
Emplaceable(Emplaceable&& x) : int_(x.int_), double_(x.double_) {
TEST_CONSTEXPR Emplaceable() : int_(0), double_(0) {}
TEST_CONSTEXPR Emplaceable(int i, double d) : int_(i), double_(d) {}
TEST_CONSTEXPR_CXX14 Emplaceable(Emplaceable&& x) : int_(x.int_), double_(x.double_) {
x.int_ = 0;
x.double_ = 0;
}
Emplaceable& operator=(Emplaceable&& x) {
TEST_CONSTEXPR_CXX14 Emplaceable& operator=(Emplaceable&& x) {
int_ = x.int_;
x.int_ = 0;
double_ = x.double_;
x.double_ = 0;
return *this;
}

bool operator==(const Emplaceable& x) const { return int_ == x.int_ && double_ == x.double_; }
bool operator<(const Emplaceable& x) const { return int_ < x.int_ || (int_ == x.int_ && double_ < x.double_); }
TEST_CONSTEXPR bool operator==(const Emplaceable& x) const { return int_ == x.int_ && double_ == x.double_; }
TEST_CONSTEXPR bool operator<(const Emplaceable& x) const {
return int_ < x.int_ || (int_ == x.int_ && double_ < x.double_);
}

int get() const { return int_; }
TEST_CONSTEXPR int get() const { return int_; }
};

template <>
struct std::hash<Emplaceable> {
typedef Emplaceable argument_type;
typedef std::size_t result_type;

std::size_t operator()(const Emplaceable& x) const { return static_cast<std::size_t>(x.get()); }
TEST_CONSTEXPR std::size_t operator()(const Emplaceable& x) const { return static_cast<std::size_t>(x.get()); }
};

#endif // TEST_STD_VER >= 11
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,38 @@
#include "test_allocator.h"

template <class T>
struct test : public std::priority_queue<T, std::vector<T, test_allocator<T> > > {
struct Test : public std::priority_queue<T, std::vector<T, test_allocator<T> > > {
typedef std::priority_queue<T, std::vector<T, test_allocator<T> > > base;
typedef typename base::container_type container_type;
typedef typename base::value_compare value_compare;

explicit test(const test_allocator<int>& a) : base(a) {}
test(const value_compare& comp, const test_allocator<int>& a) : base(comp, c, a) {}
test(const value_compare& comp, const container_type& container, const test_allocator<int>& a)
TEST_CONSTEXPR_CXX26 explicit Test(const test_allocator<int>& a) : base(a) {}
TEST_CONSTEXPR_CXX26 Test(const value_compare& comp, const test_allocator<int>& a) : base(comp, c, a) {}
TEST_CONSTEXPR_CXX26 Test(const value_compare& comp, const container_type& container, const test_allocator<int>& a)
: base(comp, container, a) {}
#if TEST_STD_VER >= 11
test(const value_compare& comp, container_type&& container, const test_allocator<int>& a)
TEST_CONSTEXPR_CXX26 Test(const value_compare& comp, container_type&& container, const test_allocator<int>& a)
: base(comp, std::move(container), a) {}
test(test&& q, const test_allocator<int>& a) : base(std::move(q), a) {}
TEST_CONSTEXPR_CXX26 Test(Test&& q, const test_allocator<int>& a) : base(std::move(q), a) {}
#endif
test_allocator<int> get_allocator() { return c.get_allocator(); }
TEST_CONSTEXPR_CXX26 test_allocator<int> get_allocator() { return c.get_allocator(); }

using base::c;
};

int main(int, char**) {
test<int> q((test_allocator<int>(3)));
TEST_CONSTEXPR_CXX26 bool test() {
Test<int> q((test_allocator<int>(3)));
assert(q.c.get_allocator() == test_allocator<int>(3));
assert(q.c.size() == 0);

return true;
}

int main(int, char**) {
assert(test());
#if TEST_STD_VER >= 26
static_assert(test());
#endif

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,38 @@
#include "test_allocator.h"

template <class T>
struct test : public std::priority_queue<T, std::vector<T, test_allocator<T> > > {
struct Test : public std::priority_queue<T, std::vector<T, test_allocator<T> > > {
typedef std::priority_queue<T, std::vector<T, test_allocator<T> > > base;
typedef typename base::container_type container_type;
typedef typename base::value_compare value_compare;

explicit test(const test_allocator<int>& a) : base(a) {}
test(const value_compare& compare, const test_allocator<int>& a) : base(compare, a) {}
test(const value_compare& compare, const container_type& container, const test_allocator<int>& a)
TEST_CONSTEXPR_CXX26 explicit Test(const test_allocator<int>& a) : base(a) {}
TEST_CONSTEXPR_CXX26 Test(const value_compare& compare, const test_allocator<int>& a) : base(compare, a) {}
TEST_CONSTEXPR_CXX26 Test(const value_compare& compare, const container_type& container, const test_allocator<int>& a)
: base(compare, container, a) {}
#if TEST_STD_VER >= 11
test(const value_compare& compare, container_type&& container, const test_allocator<int>& a)
TEST_CONSTEXPR_CXX26 Test(const value_compare& compare, container_type&& container, const test_allocator<int>& a)
: base(compare, std::move(container), a) {}
test(test&& q, const test_allocator<int>& a) : base(std::move(q), a) {}
TEST_CONSTEXPR_CXX26 Test(Test&& q, const test_allocator<int>& a) : base(std::move(q), a) {}
#endif
test_allocator<int> get_allocator() { return c.get_allocator(); }
TEST_CONSTEXPR_CXX26 test_allocator<int> get_allocator() { return c.get_allocator(); }

using base::c;
};

int main(int, char**) {
test<int> q(std::less<int>(), test_allocator<int>(3));
TEST_CONSTEXPR_CXX26 bool test() {
Test<int> q(std::less<int>(), test_allocator<int>(3));
assert(q.c.get_allocator() == test_allocator<int>(3));
assert(q.c.size() == 0);

return 0;
return true;
}

int main(int, char**) {
assert(test());
#if TEST_STD_VER >= 26
static_assert(test());
#endif

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,40 +19,49 @@
#include "test_allocator.h"

template <class C>
C make(int n) {
TEST_CONSTEXPR_CXX26 C make(int n) {
C c;
for (int i = 0; i < n; ++i)
c.push_back(i);
return c;
}

template <class T>
struct test : public std::priority_queue<T, std::vector<T, test_allocator<T> > > {
struct Test : public std::priority_queue<T, std::vector<T, test_allocator<T> > > {
typedef std::priority_queue<T, std::vector<T, test_allocator<T> > > base;
typedef typename base::container_type container_type;
typedef typename base::value_compare value_compare;

explicit test(const test_allocator<int>& a) : base(a) {}
test(const value_compare& compare, const test_allocator<int>& a) : base(compare, a) {}
test(const value_compare& compare, const container_type& container, const test_allocator<int>& a)
TEST_CONSTEXPR_CXX26 explicit Test(const test_allocator<int>& a) : base(a) {}
TEST_CONSTEXPR_CXX26 Test(const value_compare& compare, const test_allocator<int>& a) : base(compare, a) {}
TEST_CONSTEXPR_CXX26 Test(const value_compare& compare, const container_type& container, const test_allocator<int>& a)
: base(compare, container, a) {}
#if TEST_STD_VER >= 11 // testing rvalue constructor
test(const value_compare& compare, container_type&& container, const test_allocator<int>& a)
TEST_CONSTEXPR_CXX26 Test(const value_compare& compare, container_type&& container, const test_allocator<int>& a)
: base(compare, std::move(container), a) {}
test(test&& q, const test_allocator<int>& a) : base(std::move(q), a) {}
TEST_CONSTEXPR_CXX26 Test(Test&& q, const test_allocator<int>& a) : base(std::move(q), a) {}
#endif
test_allocator<int> get_allocator() { return c.get_allocator(); }
TEST_CONSTEXPR_CXX26 test_allocator<int> get_allocator() { return c.get_allocator(); }

using base::c;
};

int main(int, char**) {
TEST_CONSTEXPR_CXX26 bool test() {
typedef std::vector<int, test_allocator<int> > C;
C v = make<C>(5);
test<int> q(std::less<int>(), v, test_allocator<int>(3));
Test<int> q(std::less<int>(), v, test_allocator<int>(3));
assert(q.c.get_allocator() == test_allocator<int>(3));
assert(q.size() == 5);
assert(q.top() == 4);

return true;
}

int main(int, char**) {
assert(test());
#if TEST_STD_VER >= 26
static_assert(test());
#endif

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,39 +19,48 @@
#include "test_allocator.h"

template <class C>
C make(int n) {
TEST_CONSTEXPR_CXX26 C make(int n) {
C c;
for (int i = 0; i < n; ++i)
c.push_back(i);
return c;
}

template <class T>
struct test : public std::priority_queue<T, std::vector<T, test_allocator<T> > > {
struct Test : public std::priority_queue<T, std::vector<T, test_allocator<T> > > {
typedef std::priority_queue<T, std::vector<T, test_allocator<T> > > base;
typedef typename base::container_type container_type;
typedef typename base::value_compare value_compare;

explicit test(const test_allocator<int>& a) : base(a) {}
test(const value_compare& compare, const test_allocator<int>& a) : base(compare, a) {}
test(const value_compare& compare, const container_type& container, const test_allocator<int>& a)
TEST_CONSTEXPR_CXX26 explicit Test(const test_allocator<int>& a) : base(a) {}
TEST_CONSTEXPR_CXX26 Test(const value_compare& compare, const test_allocator<int>& a) : base(compare, a) {}
TEST_CONSTEXPR_CXX26 Test(const value_compare& compare, const container_type& container, const test_allocator<int>& a)
: base(compare, container, a) {}
#if TEST_STD_VER >= 11 // testing rvalue ctor
test(const value_compare& compare, container_type&& container, const test_allocator<int>& a)
TEST_CONSTEXPR_CXX26 Test(const value_compare& compare, container_type&& container, const test_allocator<int>& a)
: base(compare, std::move(container), a) {}
test(test&& q, const test_allocator<int>& a) : base(std::move(q), a) {}
TEST_CONSTEXPR_CXX26 Test(Test&& q, const test_allocator<int>& a) : base(std::move(q), a) {}
#endif
test_allocator<int> get_allocator() { return c.get_allocator(); }
TEST_CONSTEXPR_CXX26 test_allocator<int> get_allocator() { return c.get_allocator(); }

using base::c;
};

int main(int, char**) {
TEST_CONSTEXPR_CXX26 bool test() {
typedef std::vector<int, test_allocator<int> > C;
test<int> q(std::less<int>(), make<C>(5), test_allocator<int>(3));
Test<int> q(std::less<int>(), make<C>(5), test_allocator<int>(3));
assert(q.c.get_allocator() == test_allocator<int>(3));
assert(q.size() == 5);
assert(q.top() == 4);

return true;
}

int main(int, char**) {
assert(test());
#if TEST_STD_VER >= 26
static_assert(test());
#endif

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
#include <queue>
#include <cassert>

#include "test_macros.h"

template <class C>
C make(int n) {
TEST_CONSTEXPR_CXX26 C make(int n) {
C c;
for (int i = 0; i < n; ++i)
c.push_back(i);
Expand All @@ -26,27 +28,36 @@ C make(int n) {
#include "test_allocator.h"

template <class T>
struct test : public std::priority_queue<T, std::vector<T, test_allocator<T> > > {
struct Test : public std::priority_queue<T, std::vector<T, test_allocator<T> > > {
typedef std::priority_queue<T, std::vector<T, test_allocator<T> > > base;
typedef typename base::container_type container_type;
typedef typename base::value_compare value_compare;

explicit test(const test_allocator<int>& a) : base(a) {}
test(const value_compare& compare, const test_allocator<int>& a) : base(compare, c, a) {}
test(const value_compare& compare, const container_type& container, const test_allocator<int>& a)
TEST_CONSTEXPR_CXX26 explicit Test(const test_allocator<int>& a) : base(a) {}
TEST_CONSTEXPR_CXX26 Test(const value_compare& compare, const test_allocator<int>& a) : base(compare, c, a) {}
TEST_CONSTEXPR_CXX26 Test(const value_compare& compare, const container_type& container, const test_allocator<int>& a)
: base(compare, container, a) {}
test(const test& q, const test_allocator<int>& a) : base(q, a) {}
test_allocator<int> get_allocator() { return c.get_allocator(); }
TEST_CONSTEXPR_CXX26 Test(const Test& q, const test_allocator<int>& a) : base(q, a) {}
TEST_CONSTEXPR_CXX26 test_allocator<int> get_allocator() { return c.get_allocator(); }

using base::c;
};

int main(int, char**) {
test<int> qo(std::less<int>(), make<std::vector<int, test_allocator<int> > >(5), test_allocator<int>(2));
test<int> q(qo, test_allocator<int>(6));
TEST_CONSTEXPR_CXX26 bool test() {
Test<int> qo(std::less<int>(), make<std::vector<int, test_allocator<int> > >(5), test_allocator<int>(2));
Test<int> q(qo, test_allocator<int>(6));
assert(q.size() == 5);
assert(q.c.get_allocator() == test_allocator<int>(6));
assert(q.top() == int(4));

return true;
}

int main(int, char**) {
assert(test());
#if TEST_STD_VER >= 26
static_assert(test());
#endif

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,27 @@ struct PQ : std::priority_queue<T, Cont, Comp> {
typedef std::priority_queue<T, Cont, Comp> base;

template <class It, class Alloc>
explicit PQ(It first, It last, const Alloc& a) : base(first, last, a) {}
TEST_CONSTEXPR_CXX26 explicit PQ(It first, It last, const Alloc& a) : base(first, last, a) {}

using base::c;
};

int main(int, char**) {
TEST_CONSTEXPR_CXX26 bool test() {
int a[] = {3, 5, 2, 0, 6, 8, 1};
typedef test_allocator<int> Alloc;
PQ<int, std::vector<int, Alloc> > q(a, a + 7, Alloc(2));
assert(q.size() == 7);
assert(q.top() == 8);
assert(q.c.get_allocator() == Alloc(2));

return true;
}

int main(int, char**) {
assert(test());
#if TEST_STD_VER >= 26
static_assert(test());
#endif

return 0;
}
Loading
Loading