Skip to content

Instantly share code, notes, and snippets.

@saxbophone
Last active May 16, 2022 21:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save saxbophone/669186a3a7d0ce6d3930c858f44a0cc5 to your computer and use it in GitHub Desktop.
Save saxbophone/669186a3a7d0ce6d3930c858f44a0cc5 to your computer and use it in GitHub Desktop.
A constexpr stack-like list to prove dynamic things can be done at compile-time as long as it's all cleaned up before returning from the function
class List {
public:
constexpr ~List() {
if (next != nullptr) {
delete next;
next = nullptr;
}
}
constexpr void push(int n) {
get_end().next = new List;
get_end().value = n;
}
constexpr int pop() {
List* cursor = this;
while (cursor->next != nullptr and cursor->next->next != nullptr) {
cursor = cursor->next;
}
int v = cursor->next->value;
delete cursor->next;
cursor->next = nullptr;
return v;
}
constexpr operator int() const {
return get_end().value;
}
private:
constexpr const List& get_end() const {
if (next == nullptr) {
return *this;
} else {
return next->get_end();
}
}
constexpr List& get_end() {
if (next == nullptr) {
return *this;
} else {
return next->get_end();
}
}
List* next = nullptr;
int value = 0;
};
#include <array>
// constexpr also works fine
consteval std::array<int, 3> do_stuff() {
List l;
l.push(5);
l.push(4);
l.push(-67);
l.pop();
l.push(1337);
return {l.pop(), l.pop(), l.pop()};
}
// only GCC seems to accept this
// constinit auto [F, G, H] = do_stuff();
constinit int F = do_stuff()[0];
constinit int G = do_stuff()[1];
constinit int H = do_stuff()[2];
// Works on:
// - MSVC 19.31+
// - GCC 11.1+
// - Clang 10.0+
// - Many other compilers so long as C++20 support is decent enough
int main() {
return F * G + H;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment