diff --git a/tests/src/tests.cpp b/tests/src/tests.cpp index c5ec985..12d0684 100644 --- a/tests/src/tests.cpp +++ b/tests/src/tests.cpp @@ -26,6 +26,7 @@ #include #include #include +#include template auto run_once() @@ -150,108 +151,103 @@ namespace fb }; template - class arg_constraint_container + struct arg_constraint_container { - private: - blt::vector> map; - public: - constexpr explicit arg_constraint_container(const blt::vector>& map): map(map) - {} - - constexpr explicit arg_constraint_container(blt::size_t argc, const blt::vector& map) - { - for (blt::size_t i = 0; i < argc; i++) - this->map.push_back(map); - } - - constexpr arg_constraint_container(std::initializer_list> maps) - { - for (const auto& v : maps) - this->map.push_back(v); - } - - [[nodiscard]] constexpr const blt::vector& getAllowedArguments(blt::size_t arg) const - { - return map[arg]; - } + blt::vector> map; + + constexpr explicit arg_constraint_container(blt::size_t argc, const blt::vector& map) + { + for (blt::size_t i = 0; i < argc; i++) + this->map.push_back(map); + } + + constexpr arg_constraint_container(std::initializer_list> maps) + { + for (const auto& v : blt::enumerate(maps)) + this->map.push_back(v.second); + } }; - template + template class operator_t { private: + // std::function)> ENUM_TYPE our_type; arg_count_t argc; - std::function)> func; + Func func; arg_constraint_container allowed_inputs; - - constexpr operator_t(ENUM_TYPE type, arg_count_t argc, std::function)> func, - arg_constraint_container allowed_inputs): - our_type(type), argc(argc), func(std::move(func)), allowed_inputs(std::move(allowed_inputs)) - {} - public: - static constexpr operator_t make_operator(ENUM_TYPE type, arg_count_t argc, - std::function)> func, - arg_constraint_container allowed_inputs) - { - return operator_t{type, argc, func, allowed_inputs}; - } + constexpr operator_t(ENUM_TYPE type, arg_count_t argc, Func&& f, arg_constraint_container allowed_inputs): + our_type(type), argc(argc), func(std::forward(f)), allowed_inputs(allowed_inputs) + {} + + [[nodiscard]] constexpr Func& function() const + { return func; } + + [[nodiscard]] constexpr const arg_constraint_container& argMap() const + { return allowed_inputs; } + [[nodiscard]] constexpr arg_count_t argCount() const { return argc; } - [[nodiscard]] constexpr std::function)>& function() const - { return func; } - - [[nodiscard]] constexpr const blt::vector& getAllowedArguments(blt::size_t arg) const - { return allowed_inputs.getAllowedArguments(arg); } - [[nodiscard]] constexpr ENUM_TYPE type() const { return our_type; } }; - template - struct operator_container_constructor_t; - - template - struct operator_container_t - { - friend operator_container_constructor_t; - private: - constexpr operator_container_t(std::initializer_list>> list) - { - for (const auto& v : list) - { - operators[static_cast(v.first)] = v.second; - max_argc = std::max(v.second.argCount(), max_argc); - } - } - - public: - arg_count_t max_argc; - std::array, ENUM_MAX> operators; - - [[nodiscard]] constexpr arg_count_t getMaxArgc() const - { - return max_argc; - } - }; - - template typename ALLOC> + template class node_tree { private: - static ALLOC allocator; struct node { - std::array children; - NODE_CONTAINER caller; + ENUM_TYPE type; + std::array children; }; + static_assert(std::is_trivially_copyable_v && "The tree's internal node type must be trivially copyable!"); public: }; + template... operators> + inline constexpr auto max_args() + { + return std::max({operators.argCount()...}); + } + + template... operators> + inline constexpr auto enum_max() + { + return std::max({static_cast(operators.type())...}); + } + + template... operators> + struct gp_program_container_t + { + constexpr static inline auto MAX_OPERATORS = enum_max(); + constexpr static inline auto MAX_ARGS = max_args(); + std::array, MAX_ARGS>, MAX_OPERATORS> argument_constraints; + std::array argument_count; + std::array functions; + + + node_tree tree; + }; + + template... operators> + inline auto make_gp_program() + { + gp_program_container_t program; + for (const operator_t& op : {operators...}) + { + auto index = static_cast(op.type()); + for (const auto& v : blt::enumerate(op.argMap())) + program.argument_constraints[index][v.first] = v.second; + } + return program; + } + /* * Functions */