#ifndef CTLL__TYPE_STACK__HPP #define CTLL__TYPE_STACK__HPP #include "utilities.hpp" namespace ctll { template struct list { }; struct _nothing { }; using empty_list = list<>; // calculate size of list content template constexpr auto size(list) noexcept { return sizeof...(Ts); } // check if the list is empty template constexpr bool empty(list) noexcept { return false; } constexpr bool empty(empty_list) { return true; } // concat two lists together left to right template constexpr auto concat(list, list) noexcept -> list { return {}; } // push something to the front of a list template constexpr auto push_front(T, list) noexcept -> list { return {}; } // pop element from the front of a list template constexpr auto pop_front(list) noexcept -> list { return {}; } constexpr auto pop_front(empty_list) -> empty_list; // pop element from the front of a list and return new typelist too template struct list_pop_pair { Front front{}; List list{}; constexpr list_pop_pair() = default; }; template constexpr auto pop_and_get_front(list, T = T()) noexcept -> list_pop_pair> { return {}; } template constexpr auto pop_and_get_front(empty_list, T = T()) noexcept -> list_pop_pair { return {}; } // return front of the list template constexpr auto front(list, T = T()) noexcept -> Head { return {}; } template constexpr auto front(empty_list, T = T()) noexcept -> T { return {}; } // rotate list template struct rotate_item { template friend constexpr auto operator+(list, rotate_item) noexcept -> list { return {}; } }; template constexpr auto rotate(list) -> decltype((list<>{} + ... + rotate_item{})) { return {}; } // set operations template struct item_matcher { struct not_selected { template friend constexpr auto operator+(list, not_selected) -> list; }; template struct wrapper { template friend constexpr auto operator+(list, wrapper) -> list; }; static constexpr auto check(T) { return std::true_type{}; } static constexpr auto check(...) { return std::false_type{}; } static constexpr auto select(T) { return not_selected{}; } template static constexpr auto select(Y) { return wrapper{}; } }; template constexpr bool exists_in(T, list) noexcept { return (item_matcher::check(Ts{}) || ... || false); } template constexpr auto add_item(T item, list l) noexcept { if constexpr (exists_in(item, l)) { return l; } else { return list{}; } } template constexpr auto remove_item(T, list) noexcept { item_matcher matcher; return decltype((list<>{} + ... + matcher.select(Ts{}))){}; } } #endif