diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-10-01 00:47:41 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2019-10-01 00:47:41 +0000 |
| commit | 9f42a1231e300ceaba5bf573d4de00ffe5c8c3f4 (patch) | |
| tree | e3cec613dcc98ca318b1fc2b107dfb72c2feccb5 | |
| parent | 58c3235ee976e577ab183a3058e804f4ac1ae027 (diff) | |
| download | bcm5719-llvm-9f42a1231e300ceaba5bf573d4de00ffe5c8c3f4.tar.gz bcm5719-llvm-9f42a1231e300ceaba5bf573d4de00ffe5c8c3f4.zip | |
[c++20] Add a C++20 version of the existing turing machine test.
Unlike the C++11 version, this one uese mutable state and dynamic
allocation instead of a carefully balanced and ever-accumulating pile of
temporaries.
llvm-svn: 373281
| -rw-r--r-- | clang/test/SemaCXX/constexpr-turing-cxx2a.cpp | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/clang/test/SemaCXX/constexpr-turing-cxx2a.cpp b/clang/test/SemaCXX/constexpr-turing-cxx2a.cpp new file mode 100644 index 00000000000..0941cf408f2 --- /dev/null +++ b/clang/test/SemaCXX/constexpr-turing-cxx2a.cpp @@ -0,0 +1,66 @@ +// RUN: %clang_cc1 -verify -std=c++2a %s +// expected-no-diagnostics + +const unsigned halt = (unsigned)-1; + +enum Dir { L, R }; +struct Action { + bool tape; + Dir dir; + unsigned next; +}; +using State = Action[2]; + +// An infinite tape! +struct Tape { + constexpr Tape() = default; + constexpr ~Tape() { + if (l) { l->r = nullptr; delete l; } + if (r) { r->l = nullptr; delete r; } + } + constexpr Tape *left() { + if (!l) { l = new Tape; l->r = this; } + return l; + } + constexpr Tape *right() { + if (!r) { r = new Tape; r->l = this; } + return r; + } + Tape *l = nullptr; + bool val = false; + Tape *r = nullptr; +}; + +// Run turing machine 'tm' on tape 'tape' from state 'state'. Return number of +// steps taken until halt. +constexpr unsigned run(const State *tm) { + Tape *tape = new Tape; + unsigned state = 0; + unsigned steps = 0; + + for (state = 0; state != halt; ++steps) { + auto [val, dir, next_state] = tm[state][tape->val]; + tape->val = val; + tape = (dir == L ? tape->left() : tape->right()); + state = next_state; + } + + delete tape; + return steps; +} + +// 3-state busy beaver. S(bb3) = 21. +constexpr State bb3[] = { + { { true, R, 1 }, { true, R, halt } }, + { { true, L, 1 }, { false, R, 2 } }, + { { true, L, 2 }, { true, L, 0 } } +}; +static_assert(run(bb3) == 21, ""); + +// 4-state busy beaver. S(bb4) = 107. +constexpr State bb4[] = { + { { true, R, 1 }, { true, L, 1 } }, + { { true, L, 0 }, { false, L, 2 } }, + { { true, R, halt }, { true, L, 3 } }, + { { true, R, 3 }, { false, R, 0 } } }; +static_assert(run(bb4) == 107, ""); |

