Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- template<int first, int... rest>
- struct memory;
- struct empty {
- template<int val>
- using append = memory<val>;
- using next = empty;
- constexpr static int value = 0;
- };
- template<class l, class r>
- struct same_t {
- constexpr static bool value = false;
- };
- template<class t>
- struct same_t<t, t> {
- constexpr static bool value = true;
- };
- template<class l, class r>
- constexpr bool same_v = same_t<l, r>::value;
- template<class C, class M, class I, class O, int IP, int DP>
- struct state {
- using commands = C;
- using memory = M;
- using input = I;
- using output = O;
- constexpr static int ip = IP;
- constexpr static int dp = DP;
- };
- template<int first, int... rest>
- struct commands {
- constexpr static int current = first;
- using next = commands<rest...>;
- };
- template<int first>
- struct commands<first>{
- constexpr static int current = first;
- using next = empty;
- };
- template<class commands>
- constexpr int at(int index) {
- if constexpr (!same_v<commands, empty>) {
- if (index == 0) {
- return commands::current;
- }
- return at<typename commands::next>(index - 1);
- }
- return 0;
- }
- template<int first, int... rest>
- struct memory {
- template<int cell>
- using append = memory<first, rest..., cell>;
- constexpr static int value = first;
- using next = memory<rest...>;
- };
- template<int first>
- struct memory<first>{
- template<int cell>
- using append = memory<first, cell>;
- constexpr static int value = first;
- using next = empty;
- };
- template<int index, class memory, class part = empty>
- struct locate;
- template<class l, class r>
- struct merge;
- template<class l, class r>
- struct merge {
- using result = typename merge<typename l::template append<r::value>, typename r::next>::result;
- };
- template<class l>
- struct merge<l, empty> {
- using result = l;
- };
- template<class r>
- struct merge<empty, r> {
- using result = r;
- };
- template<int index, class memory, class part>
- struct locate {
- using result = locate<index - 1, typename memory::next, typename part::template append<memory::value>>;
- using left = typename result::left;
- constexpr static int value = result::value;
- using right = typename result::right;
- template<int new_value>
- using replace = typename merge<typename left::template append<new_value>, right>::result;
- };
- template<class memory, class part>
- struct locate<0, memory, part> {
- using left = part;
- using right = typename memory::next;
- constexpr static int value = memory::value;
- template<int new_value>
- using replace = typename merge<typename left::template append<new_value>, right>::result;
- };
- template<int first, int...values>
- struct input {
- constexpr static int current = first;
- using next = input<values...>;
- };
- template<int... values>
- struct output {
- template<int val>
- using put = output<values..., val>;
- };
- template<class state>
- constexpr void run() {
- constexpr int command = at<typename state::commands>(state::ip);
- if constexpr(command != 0) {
- if (command == '+') {
- using located = locate<state::dp, typename state::memory>;
- constexpr int result = located::value;
- return run<
- ::state<
- typename state::commands,
- typename located::template replace<result + 1>,
- typename state::input,
- typename state::output,
- state::ip + 1,
- state::dp
- >
- >();
- }
- if (command == '>') {
- return run<
- ::state<
- typename state::commands,
- typename state::memory,
- typename state::input,
- typename state::output,
- state::ip + 1,
- state::dp + 1
- >
- >();
- }
- }
- }
- int main() {
- run<
- state<
- commands<'+', '+', '+', '>', '+'>,
- memory<0, 0, 0>,
- input<0, 0, 0>,
- output<0, 0, 0>,
- 0,
- 0
- >
- >();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement