online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code   
Language
#include <iostream> #include "static-calculator.hpp" int main() { // Test basic arithmetic operations using addition_expr = typename_array<value_wrapper<'1'>, value_wrapper<'+'>, value_wrapper<'2'>>; static_assert(addition_expr::template acquire<static_calculator>::result == 3, "Test failed: Basic addition should evaluate to 3"); std::cout << "Basic addition (1+2): " << addition_expr::template acquire<static_calculator>::result << std::endl; using subtraction_expr = typename_array<value_wrapper<'5'>, value_wrapper<'-'>, value_wrapper<'2'>>; static_assert(subtraction_expr::template acquire<static_calculator>::result == 3, "Test failed: Basic subtraction should evaluate to 3"); std::cout << "Basic subtraction (5-2): " << subtraction_expr::template acquire<static_calculator>::result << std::endl; using multiplication_expr = typename_array<value_wrapper<'3'>, value_wrapper<'*'>, value_wrapper<'4'>>; static_assert(multiplication_expr::template acquire<static_calculator>::result == 12, "Test failed: Basic multiplication should evaluate to 12"); std::cout << "Basic multiplication (3*4): " << multiplication_expr::template acquire<static_calculator>::result << std::endl; using division_expr = typename_array<value_wrapper<'8'>, value_wrapper<'/'>, value_wrapper<'2'>>; static_assert(division_expr::template acquire<static_calculator>::result == 4, "Test failed: Basic division should evaluate to 4"); std::cout << "Basic division (8/2): " << division_expr::template acquire<static_calculator>::result << std::endl; using modulo_expr = typename_array<value_wrapper<'7'>, value_wrapper<'%'>, value_wrapper<'3'>>; static_assert(modulo_expr::template acquire<static_calculator>::result == 1, "Test failed: Basic modulo should evaluate to 1"); std::cout << "Basic modulo (7%3): " << modulo_expr::template acquire<static_calculator>::result << std::endl; // Test order of operations using order_expr1 = typename_array<value_wrapper<'2'>, value_wrapper<'+'>, value_wrapper<'3'>, value_wrapper<'*'>, value_wrapper<'4'>>; static_assert(order_expr1::template acquire<static_calculator>::result == 14, "Test failed: Expression with proper order of operations should evaluate to 14"); std::cout << "Order of operations (2+3*4): " << order_expr1::template acquire<static_calculator>::result << std::endl; using order_expr2 = typename_array<value_wrapper<'8'>, value_wrapper<'/'>, value_wrapper<'4'>, value_wrapper<'+'>, value_wrapper<'3'>>; static_assert(order_expr2::template acquire<static_calculator>::result == 5, "Test failed: Division and addition should evaluate to 5"); std::cout << "Division and addition (8/4+3): " << order_expr2::template acquire<static_calculator>::result << std::endl; // Test parentheses using paren_expr1 = typename_array<value_wrapper<'('>, value_wrapper<'2'>, value_wrapper<'+'>, value_wrapper<'3'>, value_wrapper<')'>, value_wrapper<'*'>, value_wrapper<'4'>>; static_assert(paren_expr1::template acquire<static_calculator>::result == 20, "Test failed: Expression with parentheses should evaluate to 20"); std::cout << "Expression with parentheses ((2+3)*4): " << paren_expr1::template acquire<static_calculator>::result << std::endl; using paren_expr2 = typename_array<value_wrapper<'2'>, value_wrapper<'*'>, value_wrapper<'('>, value_wrapper<'3'>, value_wrapper<'+'>, value_wrapper<'4'>, value_wrapper<')'>>; static_assert(paren_expr2::template acquire<static_calculator>::result == 14, "Test failed: Expression with parentheses should evaluate to 14"); std::cout << "Expression with parentheses (2*(3+4)): " << paren_expr2::template acquire<static_calculator>::result << std::endl; // Test multi-digit numbers using multi_digit_expr = typename_array<value_wrapper<'1'>, value_wrapper<'2'>, value_wrapper<'3'>, value_wrapper<'+'>, value_wrapper<'4'>, value_wrapper<'5'>, value_wrapper<'6'>>; static_assert(multi_digit_expr::template acquire<static_calculator>::result == 579, "Test failed: Expression with multi-digit numbers should evaluate to 579"); std::cout << "Multi-digit numbers (123+456): " << multi_digit_expr::template acquire<static_calculator>::result << std::endl; // Test complex expressions using complex_expr1 = typename_array<value_wrapper<'2'>, value_wrapper<'*'>, value_wrapper<'('>, value_wrapper<'3'>, value_wrapper<'+'>, value_wrapper<'4'>, value_wrapper<')'>, value_wrapper<'-'>, value_wrapper<'5'>, value_wrapper<'/'>, value_wrapper<'2'>>; static_assert(complex_expr1::template acquire<static_calculator>::result == 12, "Test failed: Complex expression should evaluate to 12"); std::cout << "Complex expression (2*(3+4)-5/2): " << complex_expr1::template acquire<static_calculator>::result << std::endl; using complex_expr2 = typename_array<value_wrapper<'('>, value_wrapper<'1'>, value_wrapper<'0'>, value_wrapper<'+'>, value_wrapper<'5'>, value_wrapper<'*'>, value_wrapper<'2'>, value_wrapper<')'>, value_wrapper<'/'>, value_wrapper<'('>, value_wrapper<'4'>, value_wrapper<'-'>, value_wrapper<'2'>, value_wrapper<')'>>; static_assert(complex_expr2::template acquire<static_calculator>::result == 10, "Test failed: Complex expression with nested parentheses should evaluate to 10"); std::cout << "Complex expression with nested parentheses ((10+5*2)/(4-2)): " << complex_expr2::template acquire<static_calculator>::result << std::endl; // Test multiple nested parentheses using nested_paren_expr = typename_array< value_wrapper<'('>, value_wrapper<'1'>, value_wrapper<'+'>, value_wrapper<'('>, value_wrapper<'('>, value_wrapper<'2'>, value_wrapper<'+'>, value_wrapper<'3'>, value_wrapper<')'>, value_wrapper<'*'>, value_wrapper<'('>, value_wrapper<'4'>, value_wrapper<'+'>, value_wrapper<'5'>, value_wrapper<')'>, value_wrapper<')'>, value_wrapper<')'> >; static_assert(nested_paren_expr::template acquire<static_calculator>::result == 46, "Test failed: Expression with multiple nested parentheses should evaluate to 46"); std::cout << "Multiple nested parentheses (1+((2+3)*(4+5))): " << nested_paren_expr::template acquire<static_calculator>::result << std::endl; return 0; }
#ifndef TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_APPLY_H #define TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_APPLY_H #include "base.hpp" /// <summary> /// Applies a function template to each type in an array, producing a new array with transformed types. /// </summary> /// <typeparam name="array_type">The source typename array containing types to transform.</typeparam> /// <typeparam name="functor_template">A template that transforms each type, receiving the type and its index. Must define ::new_type.</typeparam> template<typename array_type, template<typename, typename_array_size_type> class functor_template> struct apply { private: /// <summary> /// Helper for applying the function to each element in the array. /// </summary> /// <typeparam name="helper_array_type">The array or remaining portion being processed.</typeparam> /// <typeparam name="helper_functor_template">The transformation function template.</typeparam> /// <typeparam name="index">Current position in the array being processed.</typeparam> template<typename helper_array_type, template<typename, typename_array_size_type> class helper_functor_template, typename_array_size_type index> struct apply_helper; /// <summary> /// Helper specialization for an empty array. /// Notice that array_template uses typename... as a typename list. This is due to the fact that MSVC and GCC deduce template arguments differently. /// </summary> /// <typeparam name="array_template">The template of the array.</typeparam> /// <typeparam name="helper_functor_template">The transformation function template.</typeparam> /// <typeparam name="index">Current position in the array being processed.</typeparam> template<template<typename...> class array_template, template<typename, typename_array_size_type> class helper_functor_template, typename_array_size_type index> struct apply_helper<array_template<>, helper_functor_template, index> { /// <summary> /// The resulting array when the input is empty. /// </summary> using new_array = typename_array<>; }; /// <summary> /// Specialization for processing the last element in the array. /// </summary> /// <typeparam name="array_template">The template of the array.</typeparam> /// <typeparam name="value_type">The type of the last element.</typeparam> /// <typeparam name="helper_functor_template">The transformation function template.</typeparam> /// <typeparam name="index">Current position in the array being processed.</typeparam> template<template<typename...> class array_template, typename value_type, template<typename, typename_array_size_type> class helper_functor_template, typename_array_size_type index> struct apply_helper<array_template<value_type>, helper_functor_template, index> { /// <summary> /// The resulting array with a single transformed type. /// </summary> using new_array = typename_array<typename helper_functor_template<value_type, index>::new_value>; }; /// <summary> /// Specialization for processing an array with multiple elements. /// Recursively applies the function to each element and combines the results. /// </summary> /// <typeparam name="array_template">The template of the array.</typeparam> /// <typeparam name="other_type">The remaining types in the array.</typeparam> /// <typeparam name="value_type">The current type being processed.</typeparam> /// <typeparam name="helper_functor_template">The transformation function template.</typeparam> /// <typeparam name="index">Current position in the array being processed.</typeparam> template<template<typename...> class array_template, typename... other_type, typename value_type, template<typename, typename_array_size_type> class helper_functor_template, typename_array_size_type index> struct apply_helper<array_template<value_type, other_type...>, helper_functor_template, index> { /// <summary> /// The array resulting from combining the transformed current element with /// recursively processed remaining elements. /// </summary> using new_array = typename combine< typename_array<typename helper_functor_template<value_type, index>::new_value>, typename apply_helper<array_template<other_type...>, helper_functor_template, (index + 1)>::new_array >::new_array; }; public: /// <summary> /// The resulting array after applying the function to each element of the input array. /// </summary> using new_array = typename apply_helper<array_type, functor_template, 0>::new_array; }; #endif // TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_APPLY_H
#ifndef TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_BASE_H #define TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_BASE_H #include <type_traits> /// <summary> /// Type used for array indexing and size representation. /// </summary> using typename_array_size_type = long long; /// <summary> /// Special value indicating "no position" or "not found" in typename arrays. /// </summary> constexpr typename_array_size_type npos = -1; /// <summary> /// A compile-time container for a sequence of types. /// </summary> /// <typeparam name="arguments_type">The types to be stored in this array.</typeparam> template<typename... arguments_type> struct typename_array { /// <summary> /// The number of types contained in this array. /// </summary> static constexpr typename_array_size_type size = sizeof... (arguments_type); /// <summary> /// Transfers the types in this array to another template. /// </summary> /// <typeparam name="other_template">The destination template to receive the types.</typeparam> template<template<typename... other_type> class other_template> using acquire = other_template<arguments_type...>; }; /// <summary> /// Forward declaration for combining two typename arrays. /// </summary> /// <typeparam name="first_array_type">The first array of types.</typeparam> /// <typeparam name="second_array_type">The second array of types.</typeparam> template<typename first_array_type, typename second_array_type> struct combine; /// <summary> /// Specialized implementation for combining two typename arrays. /// Creates a new typename array that contains all types from both input arrays, /// preserving their original order (first array's types followed by second array's types). /// </summary> /// <typeparam name="array_template">The template class of both arrays (typically typename_array).</typeparam> /// <typeparam name="first_array_arguments_type">Types from the first array.</typeparam> /// <typeparam name="second_array_arguments_type">Types from the second array.</typeparam> template<template<typename...> class array_template, typename... first_array_arguments_type, typename... second_array_arguments_type> struct combine<array_template<first_array_arguments_type...>, array_template<second_array_arguments_type...>> { /// <summary> /// The resulting array type after combination. /// </summary> using new_array = array_template<first_array_arguments_type..., second_array_arguments_type...>; }; #endif // TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_BASE_H
#ifndef TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_CHECK_FOR_ALLOWED_TYPES_H #define TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_CHECK_FOR_ALLOWED_TYPES_H #include "base.hpp" #include "find.hpp" /// <summary> /// Verifies that all types in the array are present in the allowed_types list. /// </summary> /// <typeparam name="array_type">The array_type of types to validate.</typeparam> /// <typeparam name="allowed_types">The array of permitted types.</typeparam> template<typename array_type, typename allowed_types> struct check_for_allowed_types { private: /// <summary> /// Base helper structure for validation with termination condition. /// Default specialization that indicates validation failure. /// </summary> /// <typeparam name="helper_array_type">Array being validated.</typeparam> /// <typeparam name="helper_allowed_types">Array of allowed types.</typeparam> /// <typeparam name="is_continue">Flag to continue validation or terminate with failure.</typeparam> template<typename helper_array_type, typename helper_allowed_types, bool is_continue> struct check_for_allowed_types_helper { /// <summary> /// Indicates validation failure. /// </summary> static constexpr bool is_valid = false; }; /// <summary> /// Specialization for empty array case - all validation is complete. /// </summary> /// <typeparam name="helper_array_type">Empty array (validation complete).</typeparam> /// <typeparam name="helper_allowed_types">Array of allowed types.</typeparam> template<typename helper_array_type, typename helper_allowed_types> struct check_for_allowed_types_helper<helper_array_type, helper_allowed_types, true> { /// <summary> /// Indicates successful validation (all types are allowed). /// </summary> static constexpr bool is_valid = true; }; /// <summary> /// Specialization that recursively checks each type in the array. /// Continues validation only if the current type is found in the allowed types. /// </summary> /// <typeparam name="array_template">The template of the array.</typeparam> /// <typeparam name="value_type">Current type being checked.</typeparam> /// <typeparam name="other_type">Remaining types to check.</typeparam> /// <typeparam name="helper_allowed_types">Array of allowed types.</typeparam> template<template<typename...> class array_template, typename value_type, typename... other_type, typename helper_allowed_types> struct check_for_allowed_types_helper<array_template<value_type, other_type...>, helper_allowed_types, true> { /// <summary> /// Recursively validates remaining types, continuing only if current type is allowed. /// Uses find to determine if the current type exists in the allowed_types array. /// </summary> static constexpr bool is_valid = check_for_allowed_types_helper< array_template<other_type...>, helper_allowed_types, (find<helper_allowed_types, value_type>::index != npos) >::is_valid; }; public: /// <summary> /// Result of validation. True if all types in the array are found /// in the allowed_types list, false otherwise. /// </summary> static constexpr bool is_valid = check_for_allowed_types_helper<array_type, allowed_types, true>::is_valid; }; #endif // TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_CHECK_FOR_ALLOWED_TYPES_H
#ifndef TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_COUNT_H #define TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_COUNT_H #include "base.hpp" /// <summary> /// Counts occurrences of a specific type within a typename_array. /// </summary> /// <typeparam name="array_type">The typename array to search within.</typeparam> /// <typeparam name="type_to_count">The type to count occurrences of.</typeparam> template<typename array_type, typename type_to_count> struct count { private: /// <summary> /// Base helper structure for counting type occurrences. /// Provides the final count when recursion is complete. /// </summary> /// <typeparam name="helper_array_type">Array or remaining portion being processed.</typeparam> /// <typeparam name="helper_type_to_count">The type being counted.</typeparam> /// <typeparam name="appearances_counter">Running count of occurrences found so far.</typeparam> template<typename helper_array_type, typename helper_type_to_count, typename_array_size_type appearances_counter> struct count_helper { /// <summary> /// The accumulated count of matching types. /// </summary> static constexpr typename_array_size_type counter = appearances_counter; }; /// <summary> /// Specialization for when the current type doesn't match the target type. /// Continues recursion without incrementing the counter. /// </summary> /// <typeparam name="array_template">The template of the array.</typeparam> /// <typeparam name="value_type">Current type being examined (non-matching).</typeparam> /// <typeparam name="other_types">Remaining types in the array.</typeparam> /// <typeparam name="helper_type_to_count">The type being counted.</typeparam> /// <typeparam name="appearances_counter">Running count of occurrences found so far.</typeparam> template<template<typename...> class array_template, typename value_type, typename... other_types, typename helper_type_to_count, typename_array_size_type appearances_counter> struct count_helper<array_template<value_type, other_types...>, helper_type_to_count, appearances_counter> { /// <summary> /// Continues counting in the rest of the array without incrementing. /// </summary> static constexpr typename_array_size_type counter = count_helper< array_template<other_types...>, helper_type_to_count, appearances_counter >::counter; }; /// <summary> /// Specialization for when the current type matches the target type. /// Increments the counter and continues recursion. /// </summary> /// <typeparam name="array_template">The template of the array.</typeparam> /// <typeparam name="other_types">Remaining types in the array.</typeparam> /// <typeparam name="helper_type_to_count">The type being counted (matched).</typeparam> /// <typeparam name="appearances_counter">Running count of occurrences found so far.</typeparam> template<template<typename...> class array_template, typename... other_types, typename helper_types_to_count, typename_array_size_type appearances_counter> struct count_helper<array_template<helper_types_to_count, other_types...>, helper_types_to_count, appearances_counter> { /// <summary> /// Continues counting in the rest of the array after incrementing the counter. /// </summary> static constexpr typename_array_size_type counter = count_helper< array_template<other_types...>, helper_types_to_count, (appearances_counter + 1) >::counter; }; public: /// <summary> /// The total number of occurrences of the specified type in the array. /// </summary> static constexpr typename_array_size_type counter = count_helper<array_type, type_to_count, 0>::counter; }; #endif // TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_COUNT_H
#ifndef TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_CUT_H #define TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_CUT_H #include "base.hpp" /// <summary> /// Extracts a subset of types from a typename array based on specified indices. /// </summary> /// <typeparam name="start_index">The starting index (inclusive) of the range to extract.</typeparam> /// <typeparam name="end_index">The ending index (inclusive) of the range to extract.</typeparam> /// <typeparam name="array_type">The source typename array to extract types from.</typeparam> template<typename_array_size_type start_index, typename_array_size_type end_index, typename array_type> struct cut { private: /// <summary> /// Base helper template for cutting arrays. /// </summary> /// <typeparam name="use">Whether the current element should be included.</typeparam> /// <typeparam name="index">Current position in the source array.</typeparam> /// <typeparam name="helper_array_type">Type holding the remaining elements to process.</typeparam> template<bool use, typename_array_size_type index, typename helper_array_type> struct cut_helper { /// <summary> /// Empty result for base case or when no elements match the criteria. /// </summary> using new_array = typename_array<>; }; /// <summary> /// Specialization for processing elements that are outside the requested range. /// Skips the current element and continues recursively. /// </summary> /// <typeparam name="use">Whether the current element should be included (false in this case).</typeparam> /// <typeparam name="index">Current position in the source array.</typeparam> /// <typeparam name="value_type">The current type being processed.</typeparam> /// <typeparam name="other_types">The remaining types in the source array.</typeparam> /// <typeparam name="array_template">The template class of the source array.</typeparam> template<bool use, typename_array_size_type index, typename value_type, typename... other_types, template<typename...> class array_template> struct cut_helper<use, index, array_template<value_type, other_types...>> { static constexpr typename_array_size_type next_index = index + 1; using new_array = typename cut_helper< ((next_index >= start_index) && (next_index <= end_index)), next_index, array_template<other_types...> >::new_array; }; /// <summary> /// Specialization for processing elements that are within the requested range. /// Includes the current element and continues recursively. /// </summary> /// <typeparam name="index">Current position in the source array.</typeparam> /// <typeparam name="value_type">The current type being processed.</typeparam> /// <typeparam name="other_types">The remaining types in the source array.</typeparam> /// <typeparam name="array_template">The template class of the source array.</typeparam> template<typename_array_size_type index, typename value_type, typename... other_types, template<typename...> class array_template> struct cut_helper<true, index, array_template<value_type, other_types...>> { static constexpr typename_array_size_type next_index = index + 1; using new_array = typename combine< array_template<value_type>, typename cut_helper< ((next_index >= start_index) && (next_index <= end_index)), next_index, array_template<other_types...> >::new_array >::new_array; }; public: /// <summary> /// The resulting array containing only the types from the specified index range. /// Returns an empty array if start/end indices are invalid (if start > end, /// start is negative, or end is beyond array bounds). /// </summary> using new_array = typename cut_helper<(start_index == 0) && (end_index >= start_index) && (end_index < array_type::size), 0, array_type>::new_array; static_assert(start_index >= 0, "Invalid start index: must be non-negative."); static_assert(end_index < array_type::size, "Invalid end index: must be within array bounds."); }; #endif // TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_CUT_H
#ifndef TYPENAME_ARRAY_TYPENAME_PRIMITIVES_ERASE_H #define TYPENAME_ARRAY_TYPENAME_PRIMITIVES_ERASE_H #include "base.hpp" /// <summary> /// Removes a type at the specified index from a typename array. /// </summary> /// <typeparam name="index_to_erase">The zero-based index of the type to remove.</typeparam> /// <typeparam name="array_type">The typename array to remove the type from.</typeparam> template<typename_array_size_type index_to_erase, typename array_type> struct erase { public: /// <summary> /// Helper template for implementation of type erasure at specific index. /// </summary> /// <typeparam name="index">Current index being processed during recursion.</typeparam> /// <typeparam name="helper_array_type">The array being processed.</typeparam> template<typename_array_size_type index, typename helper_array_type> struct erase_helper; /// <summary> /// Specialization for when the current index matches the index to erase. /// Skips the current type and keeps only the remaining types. /// </summary> /// <typeparam name="array_template">The template for the array container.</typeparam> /// <typeparam name="value_type">The type at the index to be erased.</typeparam> /// <typeparam name="other_types">The remaining types in the array.</typeparam> template<template<typename...> class array_template, typename value_type, typename... other_types> struct erase_helper<index_to_erase, array_template<value_type, other_types...>> { /// <summary> /// The resulting array after removing the type at the specified index. /// </summary> using new_array = typename_array<other_types...>; }; /// <summary> /// Specialization for when the current index doesn't match the index to erase. /// Keeps the current type and continues processing the rest of the array. /// </summary> /// <typeparam name="index">Current index being processed during recursion.</typeparam> /// <typeparam name="array_template">The template for the array container.</typeparam> /// <typeparam name="value_type">The type at the current index.</typeparam> /// <typeparam name="other_types">The remaining types in the array.</typeparam> template<typename_array_size_type index, template<typename...> class array_template, typename value_type, typename... other_types> struct erase_helper<index, array_template<value_type, other_types...>> { /// <summary> /// The resulting array, combining the current type with the result of processing the rest. /// </summary> using new_array = typename combine< typename_array<value_type>, typename erase_helper<index + 1, typename_array<other_types...>>::new_array >::new_array; }; public: /// <summary> /// The final array type after erasing the specified type. /// </summary> using new_array = typename erase_helper<0, array_type>::new_array; static_assert(index_to_erase < array_type::size, "Index to erase is out of bounds for the array size."); }; #endif // TYPENAME_ARRAY_TYPENAME_PRIMITIVES_ERASE_H
#ifndef TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_FIND_H #define TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_FIND_H #include "base.hpp" /// <summary> /// Searches for a specific type in a typename array and provides its index. /// </summary> /// <typeparam name="array_type">The typename array to search within.</typeparam> /// <typeparam name="helper_type_to_find">The type to find in the array.</typeparam> template<typename array_type, typename type_to_find> struct find { private: /// <summary> /// Base helper structure for finding a type. /// Default case when the type is not found - returns npos. /// </summary> /// <typeparam name="helper_array_type">The array or remaining portion being searched.</typeparam> /// <typeparam name="helper_type_to_find">The type to find.</typeparam> /// <typeparam name="index">Current position in the search.</typeparam> template<typename helper_array_type, typename helper_type_to_find, typename_array_size_type index> struct find_helper { /// <summary> /// When no match is found, returns npos (-1). /// </summary> static constexpr typename_array_size_type indx = npos; }; /// <summary> /// Specialization for when the current type doesn't match the target. /// Continues the search in the rest of the array. /// </summary> /// <typeparam name="array_template">The template of the array.</typeparam> /// <typeparam name="value_type">Current type (non-matching).</typeparam> /// <typeparam name="other_type">Remaining types in the array.</typeparam> /// <typeparam name="helper_type_to_find">The type to find.</typeparam> /// <typeparam name="index">Current position in the search.</typeparam> template<template<typename...> class array_template, typename value_type, typename... other_type, typename helper_type_to_find, typename_array_size_type index> struct find_helper<array_template<value_type, other_type...>, helper_type_to_find, index> { /// <summary> /// Recursively search in the remaining types, incrementing the index. /// </summary> static constexpr typename_array_size_type indx = find_helper<array_template<other_type...>, helper_type_to_find, index + 1>::indx; }; /// <summary> /// Specialization for when the current type matches the target. /// Terminates the search and returns the current index. /// </summary> /// <typeparam name="array_template">The template of the array.</typeparam> /// <typeparam name="other_type">Remaining types in the array.</typeparam> /// <typeparam name="helper_type_to_find">The matching type found.</typeparam> /// <typeparam name="index">Current position in the search (result).</typeparam> template<template<typename...> class array_template, typename... other_type, typename helper_type_to_find, typename_array_size_type index> struct find_helper<array_template<helper_type_to_find, other_type...>, helper_type_to_find, index> { /// <summary> /// Returns the current index as the match is found. /// </summary> static constexpr typename_array_size_type indx = index; }; public: /// <summary> /// The index of the first occurrence of type_to_find in the array, /// or npos (-1) if the type is not present. /// </summary> static constexpr typename_array_size_type index = find_helper<array_type, type_to_find, 0>::indx; }; #endif // TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_FIND_H
#ifndef TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_FIND_IF_H #define TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_FIND_IF_H #include "base.hpp" /// <summary> /// Finds the first type in a typename array that satisfies a given predicate. /// </summary> /// <typeparam name="array_type">The typename array to search in.</typeparam> /// <typeparam name="predicate_template">A template that takes a type and provides a static boolean 'value' member.</typeparam> template<typename array_type, template<typename> class predicate_template> struct find_if { private: /// <summary> /// Base case for the find_if algorithm. Called when array is empty or recursion is complete. /// </summary> /// <typeparam name="index">Current position in the array.</typeparam> /// <typeparam name="found">Indicates whether a matching type has been found.</typeparam> /// <typeparam name="helper_array_type">The remaining part of the array to process.</typeparam> template<typename_array_size_type index, bool found, typename helper_array_type> struct find_if_helper { static constexpr typename_array_size_type indx = npos; }; /// <summary> /// Recursive case for the find_if algorithm. Processes the next type in the array. /// </summary> /// <typeparam name="index">Current position in the array.</typeparam> /// <typeparam name="found">Indicates whether a matching type has been found.</typeparam> /// <typeparam name="value_type">The current type being checked.</typeparam> /// <typeparam name="other_types">Remaining types in the array.</typeparam> /// <typeparam name="array_template">The template used for the array.</typeparam> template<typename_array_size_type index, typename value_type, typename... other_types, template<typename...> class array_template> struct find_if_helper<index, false, array_template<value_type, other_types...>> { static constexpr typename_array_size_type indx = find_if_helper< index + 1, predicate_template<value_type>::value, array_template<other_types...> >::indx; }; /// <summary> /// Specialization for when a matching type has been found. Stops recursion and returns the index. /// </summary> /// <typeparam name="index">Current position in the array.</typeparam> /// <typeparam name="other_types">Remaining types in the array (ignored).</typeparam> /// <typeparam name="array_template">The template used for the array.</typeparam> template<typename_array_size_type index, typename... other_types, template<typename...> class array_template> struct find_if_helper<index, true, array_template<other_types...>> { static constexpr typename_array_size_type indx = index - 1; }; public: /// <summary> /// The index of the first type in the array that satisfies the predicate, or npos if no such type exists. /// </summary> static constexpr typename_array_size_type index = find_if_helper<0, false, array_type>::indx; }; #endif // TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_FIND_IF_H
#ifndef TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_FIND_N_APPEARANCE_H #define TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_FIND_N_APPEARANCE_H #include "base.hpp" /// <summary> /// Finds the index of the Nth appearance of a specific type in a typename array. /// </summary> /// <typeparam name="array_type">The typename array to search in.</typeparam> /// <typeparam name="type_to_find">The type to find within the array.</typeparam> /// <typeparam name="counter">The occurrence number to find (1 for first appearance, 2 for second, etc.).</typeparam> template<typename array_type, typename type_to_find, typename_array_size_type counter> struct find_n_appearance { private: /// <summary> /// Base helper struct for the recursive search algorithm. /// Returns npos when the type is not found or count appearances don't exist. /// </summary> /// <typeparam name="helper_array_type">The array type being searched.</typeparam> /// <typeparam name="helper_type_to_find">The type being searched for.</typeparam> /// <typeparam name="helper_counter">The remaining occurrences to find.</typeparam> /// <typeparam name="index">The current position in the array.</typeparam> /// <typeparam name="dummy">Boolean flag to control template specialization selection.</typeparam> template<typename helper_array_type, typename helper_type_to_find, typename_array_size_type helper_counter, typename_array_size_type index, bool dummy> struct find_n_appearance_helper { static constexpr typename_array_size_type indx = npos; }; /// <summary> /// Specialization for when the current type doesn't match the search type. /// Continues searching through the rest of the array. /// </summary> /// <typeparam name="array_template">The template class of the array.</typeparam> /// <typeparam name="value_type">The current type being examined (not matching the search type).</typeparam> /// <typeparam name="helper_type_to_find">The type being searched for.</typeparam> /// <typeparam name="other_types">The remaining types in the array.</typeparam> /// <typeparam name="helper_counter">The remaining occurrences to find.</typeparam> /// <typeparam name="index">The current position in the array.</typeparam> template<template<typename...> class array_template, typename value_type, typename helper_type_to_find, typename... other_types, typename_array_size_type helper_counter, typename_array_size_type index> struct find_n_appearance_helper<array_template<value_type, other_types...>, helper_type_to_find, helper_counter, index, true> { static constexpr typename_array_size_type indx = find_n_appearance_helper< array_template<other_types...>, helper_type_to_find, helper_counter, (index + 1), true >::indx; }; /// <summary> /// Specialization for when the current type matches the search type. /// Decrements the count and continues searching if more occurrences are needed. /// </summary> /// <typeparam name="array_template">The template class of the array.</typeparam> /// <typeparam name="helper_type_to_find">The type being searched for and currently matched.</typeparam> /// <typeparam name="other_types">The remaining types in the array.</typeparam> /// <typeparam name="helper_counter">The remaining occurrences to find.</typeparam> /// <typeparam name="index">The current position in the array.</typeparam> template<template<typename...> class array_template, typename helper_type_to_find, typename... other_types, typename_array_size_type helper_counter, typename_array_size_type index> struct find_n_appearance_helper<array_template<helper_type_to_find, other_types...>, helper_type_to_find, helper_counter, index, true> { static constexpr typename_array_size_type indx = find_n_appearance_helper< array_template<other_types...>, helper_type_to_find, (helper_counter - 1), (index + 1), ((helper_counter - 1) != 0) >::indx; }; /// <summary> /// Specialization for when the required number of occurrences has been found. /// Returns the current index (minus 1) as the position of the last match. /// </summary> /// <typeparam name="array_template">The template class of the array.</typeparam> /// <typeparam name="other_types">The remaining types in the array (no longer examined).</typeparam> /// <typeparam name="helper_type_to_find">The type that was being searched for.</typeparam> /// <typeparam name="index">The current position in the array.</typeparam> template<template<typename...> class array_template, typename... other_types, typename helper_type_to_find, typename_array_size_type index> struct find_n_appearance_helper<array_template<other_types...>, helper_type_to_find, 0, index, false> { static constexpr typename_array_size_type indx = (index - 1); }; public: /// <summary> /// The index of the Nth appearance of the specified type in the array, /// or npos if the type doesn't appear N times. /// </summary> static constexpr typename_array_size_type index = find_n_appearance_helper<array_type, type_to_find, counter, 0, true>::indx; }; #endif // TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_FIND_N_APPEARANCE_H
#ifndef TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_FIND_ONE_OF_H #define TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_FIND_ONE_OF_H #include "base.hpp" #include "find.hpp" /// <summary> /// Finds the first occurrence of any type from one array within another array. /// </summary> /// <typeparam name="array_type">The typename array to search within.</typeparam> /// <typeparam name="array_to_find_type">The array of types to search for.</typeparam> template<typename array_type, typename array_to_find_type> struct find_one_of { private: /// <summary> /// Base helper structure for finding any type from one array in another. /// Returns npos when no match is found. /// </summary> /// <typeparam name="helper_array_type">Array or remaining portion being processed.</typeparam> /// <typeparam name="helper_array_to_find_type">The array of types to search for.</typeparam> /// <typeparam name="index">Current position in the search.</typeparam> /// <typeparam name="is_found">Flag indicating if a match has been found.</typeparam> template<typename helper_array_type, typename helper_array_to_find_type, typename_array_size_type index, bool is_found> struct find_one_of_helper { /// <summary> /// Default case: no match found, return npos. /// </summary> static constexpr typename_array_size_type indx = npos; }; /// <summary> /// Specialization for when a match hasn't been found yet. /// Continues recursion, checking if the current type exists in the array_to_find. /// </summary> /// <typeparam name="array_template">The template of the array.</typeparam> /// <typeparam name="value_type">Current type being examined.</typeparam> /// <typeparam name="other_types">Remaining types in the array.</typeparam> /// <typeparam name="helper_array_to_find_type">The array of types to search for.</typeparam> /// <typeparam name="index">Current position in the search.</typeparam> template<template<typename...> class array_template, typename value_type, typename... other_types, typename helper_array_to_find_type, typename_array_size_type index> struct find_one_of_helper<array_template<value_type, other_types...>, helper_array_to_find_type, index, false> { /// <summary> /// Continues searching, using find to check if val exists in helper_array_to_find. /// </summary> static constexpr typename_array_size_type indx = find_one_of_helper< array_template<other_types...>, helper_array_to_find_type, index + 1, (find<helper_array_to_find_type, value_type>::index != -1) >::indx; }; /// <summary> /// Specialization for when a match has been found. /// Stops recursion and returns the current index. /// </summary> /// <typeparam name="helper_array_type">Array or remaining portion being processed.</typeparam> /// <typeparam name="helper_array_to_find_type">The array of types to search for.</typeparam> /// <typeparam name="index">Current position in the search.</typeparam> template<typename helper_array_type, typename helper_array_to_find_type, typename_array_size_type index> struct find_one_of_helper<helper_array_type, helper_array_to_find_type, index, true> { /// <summary> /// Match found, return the current index. /// </summary> static constexpr typename_array_size_type indx = index; }; public: /// <summary> /// The index of the first occurrence of any type from array_to_find in array, /// or npos if none are found. /// </summary> static constexpr typename_array_size_type index = find_one_of_helper<array_type, array_to_find_type, -1, false>::indx; }; #endif // TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_FIND_ONE_OF_H
#ifndef TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_FIND_PRIORITY_H #define TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_FIND_PRIORITY_H #include "base.hpp" #include "find.hpp" #include "value-wrapper.hpp" /// <summary> /// Finds the first type from array_to_find that exists in the array, returning its index. /// </summary> /// <typeparam name="array_type">The typename array to search within.</typeparam> /// <typeparam name="array_to_find_type">Array of types to search for in priority order.</typeparam> template<typename array_type, typename array_to_find_type> struct find_priority { private: /// <summary> /// Base helper structure for priority search implementation. /// Returns npos when no matching types are found. /// </summary> /// <typeparam name="helper_array_type">Array being searched.</typeparam> /// <typeparam name="helper_array_to_find_type">Remaining types to search for.</typeparam> template<typename helper_array_type, typename helper_array_to_find_type> struct find_priority_helper { /// <summary> /// Default result when no match is found. /// </summary> static constexpr typename_array_size_type get_value = npos; }; /// <summary> /// Specialization that recursively searches for types in priority order. /// Attempts to find the first type (value_type), falling back to the next type if not found. /// </summary> /// <typeparam name="array_template">The template of the array_to_find.</typeparam> /// <typeparam name="value_type">Current type to search for.</typeparam> /// <typeparam name="other_types">Remaining types to search for if current type not found.</typeparam> /// <typeparam name="helper_array_type">The array being searched.</typeparam> template<template<typename...> class array_template, typename value_type, typename... other_types, typename helper_array_type> struct find_priority_helper<helper_array_type, array_template<value_type, other_types...>> { /// <summary> /// Determines whether to continue with the current match or try the next type. /// </summary> using trailing_result = std::conditional_t< (find<helper_array_type, value_type>::index == -1), find_priority_helper<helper_array_type, array_template<other_types...>>, value_wrapper<find<helper_array_type, value_type>::index> >; /// <summary> /// The index of the first matching type found, or npos if none found. /// Notice that "get_value" is used everywhere, this is due to the fact that it needs to be compatible with value_wrapper. /// </summary> static constexpr typename_array_size_type get_value = trailing_result::get_value; }; public: /// <summary> /// The index of the first type from array_to_find found in array, or npos if none found. /// Types are checked in the order they appear in array_to_find. /// </summary> static constexpr typename_array_size_type index = find_priority_helper<array_type, array_to_find_type>::get_value; }; #endif // TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_FIND_PRIORITY_H
#ifndef TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_GET_H #define TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_GET_H #include "base.hpp" /// <summary> /// Retrieves the type at a specific index within a typename_array. /// </summary> /// <typeparam name="index">The zero-based index of the element to retrieve.</typeparam> /// <typeparam name="array_type">The typename array to retrieve from.</typeparam> template<typename_array_size_type index, typename array_type> struct get { private: /// <summary> /// Helper structure for recursively accessing elements at a specific index. /// </summary> /// <typeparam name="counter">Current recursion depth/index position.</typeparam> /// <typeparam name="helper_array_type">Array or remaining portion being processed.</typeparam> template<typename_array_size_type counter, typename helper_array_type> struct get_helper; /// <summary> /// Specialization for when the counter reaches zero (target index found). /// </summary> /// <typeparam name="array_template">The template of the array.</typeparam> /// <typeparam name="value_type">The type at the target index position.</typeparam> /// <typeparam name="other_types">Remaining types in the array (not used in this specialization).</typeparam> template<template<typename...> class array_template, typename value_type, typename... other_types> struct get_helper<0, array_template<value_type, other_types...>> { /// <summary> /// The type at the target index. /// </summary> using value = value_type; }; /// <summary> /// Specialization for recursive traversal when counter is greater than zero. /// </summary> /// <typeparam name="counter">Remaining steps to reach target index.</typeparam> /// <typeparam name="array_template">The template of the array.</typeparam> /// <typeparam name="value_type">Current type being examined (skipped).</typeparam> /// <typeparam name="other_types">Remaining types in the array.</typeparam> template<typename_array_size_type counter, template<typename...> class array_template, typename value_type, typename... other_types> struct get_helper<counter, array_template<value_type, other_types...>> { /// <summary> /// Recursively access the next element by decrementing the counter. /// </summary> using value = typename get_helper<counter - 1, typename_array<other_types...>>::value; }; public: static_assert(index < array_type::size, "Index out of bounds in typename_array::get."); static_assert(index >= 0, "Index must be greater than or equal to 0 in typename_array::get."); /// <summary> /// The type at the specified index position in the array. /// </summary> using value = typename get_helper<index, array_type>::value; }; #endif // TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_GET_H
#ifndef TYPENAME_ARRAY_INCLUDE_ALL_NAMESPACE_H #define TYPENAME_ARRAY_INCLUDE_ALL_NAMESPACE_H namespace typename_array_primitives { #include "apply.hpp" #include "base.hpp" #include "check-for-allowed-types.hpp" #include "count.hpp" #include "cut.hpp" #include "erase.hpp" #include "find.hpp" #include "find-if.hpp" #include "find-n-appearance.hpp" #include "find-one-of.hpp" #include "find-priority.hpp" #include "get.hpp" #include "insert.hpp" #include "int-to-symbols.hpp" #include "left-to-right.hpp" #include "replace.hpp" #include "replace-part.hpp" #include "sort.hpp" #include "static-calculator.hpp" #include "static-pow.hpp" #include "sum.hpp" #include "symbols-to-int.hpp" #include "typename-binder.hpp" #include "unique-add.hpp" #include "value-wrapper.hpp" } #endif // TYPENAME_ARRAY_INCLUDE_ALL_NAMESPACE_H
#ifndef TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_INSERT_H #define TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_INSERT_H #include "base.hpp" /// <summary> /// Inserts a new type at a specified index within a typename_array. /// </summary> /// <typeparam name="insert_index">The index at which to insert the new type.</typeparam> /// <typeparam name="array_type">The typename array to insert into.</typeparam> /// <typeparam name="new_type">The type to insert.</typeparam> template<typename_array_size_type insert_index, typename array_type, typename new_type> struct insert { private: /// <summary> /// Base helper structure for inserting a type at a specific index. /// </summary> /// <typeparam name="index">Current position in the array.</typeparam> /// <typeparam name="helper_array_type">Array or remaining portion being processed.</typeparam> /// <typeparam name="helper_new_type">The type being inserted.</typeparam> template<typename_array_size_type index, typename helper_array_type, typename helper_new_type> struct insert_helper { using new_array = typename_array<>; }; /// <summary> /// Specialization for an empty array. If it was chosen, it means that /// insertion is at index == array_type::size. /// </summary> /// <typeparam name="index">Current position in the array.</typeparam> /// <typeparam name="array_template">Empty template array.</typeparam> /// <typeparam name="helper_new_type">The type being inserted.</typeparam> template<typename_array_size_type index, template<typename...> class array_template, typename helper_new_type> struct insert_helper<index, array_template<>, helper_new_type> { /// <summary> /// If the array is empty, the new type is inserted immediately. /// </summary> using new_array = typename_array<helper_new_type>; static_assert(index == array_type::size, "Should never fail."); }; /// <summary> /// Specialization for processing elements before the insertion point. /// Preserves the current element and continues recursion. /// </summary> /// <typeparam name="index">Current position in the array.</typeparam> /// <typeparam name="array_template">The template of the array.</typeparam> /// <typeparam name="helper_new_type">The type being inserted.</typeparam> /// <typeparam name="value_type">Current type being processed.</typeparam> /// <typeparam name="other_types">Remaining types in the array.</typeparam> template<typename_array_size_type index, template<typename...> class array_template, typename helper_new_type, typename value_type, typename... other_types> struct insert_helper<index, array_template<value_type, other_types...>, helper_new_type> { /// <summary> /// Combines the current value with the result of processing the remaining array. /// </summary> using next = typename combine< typename_array<value_type>, typename insert_helper<index + 1, array_template<other_types...>, helper_new_type>::new_array >::new_array; /// <summary> /// The resulting array after inserting the new element at current index. /// </summary> using current_inserted = typename combine< typename_array<helper_new_type>, array_template<value_type, other_types...> >::new_array; /// <summary> /// A rather imperfect solution, initial implementation stopped /// immediately after the insertion. However, it was not portable. /// I was unable to think of anything better than this. /// </summary> using new_array = std::conditional_t< index == insert_index, current_inserted, next >; }; public: static_assert(insert_index <= array_type::size, "Insert index must be less than or equal to the size of the array typename_array::insert."); static_assert(insert_index >= 0, "Insert index must be non-negative typename_array::insert."); /// <summary> /// The resulting array after inserting the new type at the specified index. /// </summary> using new_array = typename insert_helper<0, array_type, new_type>::new_array; }; #endif // TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_INSERT_H
#ifndef TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_INT_TO_SYMBOLS_H #define TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_INT_TO_SYMBOLS_H #include "base.hpp" #include "value-wrapper.hpp" /// <summary> /// Converts an integer value to a typename_array of value_wrapper characters. /// </summary> /// <typeparam name="value">The integer value to convert to character symbols.</typeparam> template<typename_array_size_type value> struct int_to_symbols { private: /// <summary> /// Helper structure for converting integers to character symbols. /// Handles the recursive decomposition of multi-digit numbers. /// </summary> /// <typeparam name="helper_value">The current value being processed.</typeparam> template<typename_array_size_type helper_value> struct int_to_symbols_helper { /// <summary> /// Resulting array type containing character representations. /// For single digits (0-9), creates a simple array with one character. /// For multi-digit numbers, recursively processes the value. /// </summary> using array = std::conditional_t< (helper_value < 10), typename_array<value_wrapper<static_cast<char>('0' + helper_value)>>, typename combine< typename int_to_symbols<(helper_value / 10)>::array, typename_array<value_wrapper<static_cast<char>('0' + (helper_value % 10))>> >::new_array >; }; public: /// <summary> /// The resulting typename_array containing character representations of the integer. /// Add minus sign if necessary. /// </summary> using array = std::conditional_t< (value < 0), typename combine<typename_array<value_wrapper<'-'>>, typename int_to_symbols_helper<-value>::array>::new_array, typename int_to_symbols_helper<value>::array >; }; // Usually the style is that all specializations are defined inside base struct. // However, here it is most likely impossible to implement without explicit full specialization for 0. // This is because the recursive template specialization would not terminate for 0. template<> struct int_to_symbols<0> { /// <summary> /// Array containing the character '0'. /// </summary> using array = typename_array<value_wrapper<'0'>>; }; #endif // TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_INT_TO_SYMBOLS_H
#ifndef TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_LEFT_TO_RIGHT_H #define TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_LEFT_TO_RIGHT_H #include "base.hpp" /// <summary> /// Reverses the order of types in a typename_array, from left to right. /// </summary> /// <typeparam name="array_type">The typename array to reverse.</typeparam> template<typename array_type> struct left_to_right { private: /// <summary> /// Base helper structure for reversing the order of types. /// Provides the final reversed array when recursion is complete. /// </summary> /// <typeparam name="counter">Position counter for tracking progress through the array.</typeparam> /// <typeparam name="helper_array_type">Array or remaining portion being processed.</typeparam> template<typename_array_size_type counter, typename helper_array_type> struct left_to_right_helper { /// <summary> /// The resulting array after reversal operations. /// </summary> using new_array = helper_array_type; }; /// <summary> /// Specialization that processes each type in the array from left to right, /// building a new array with reversed order. /// </summary> /// <typeparam name="counter">Position counter for tracking progress through the array.</typeparam> /// <typeparam name="array_template">The template of the array.</typeparam> /// <typeparam name="value_type">Current type being processed.</typeparam> /// <typeparam name="other_types">Remaining types in the array.</typeparam> template<typename_array_size_type counter, template<typename...> class array_template, typename value_type, typename... other_types> struct left_to_right_helper<counter, array_template<value_type, other_types...>> { /// <summary> /// Recursively builds the reversed array by combining the result of /// processing remaining types with the current type. /// </summary> using new_array = typename combine< typename left_to_right_helper<counter - 1, typename_array<other_types...>>::new_array, typename_array<value_type> >::new_array; }; public: /// <summary> /// The resulting array with types in reversed order. /// </summary> using new_array = typename left_to_right_helper<array_type::size, array_type>::new_array; }; #endif // TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_LEFT_TO_RIGHT_H
#ifndef TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_REPLACE_H #define TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_REPLACE_H #include "base.hpp" /// <summary> /// Replaces a type at a specific index in a typename array with a new type. /// </summary> /// <typeparam name="replace_index">The index where the type will be replaced.</typeparam> /// <typeparam name="array_type">The source typename array.</typeparam> /// <typeparam name="new_type">The new type that will replace the existing one.</typeparam> template<typename_array_size_type replace_index, typename array_type, typename new_type> struct replace { private: /// <summary> /// Forward declaration of the helper structure for replacing types in the array. /// </summary> /// <typeparam name="index">Current position in the array being processed.</typeparam> /// <typeparam name="helper_array_type">The array or remaining portion being processed.</typeparam> /// <typeparam name="helper_new_type">The new type to insert at the target position.</typeparam> template<typename_array_size_type index, typename helper_array_type, typename helper_new_type> struct replace_helper; /// <summary> /// Specialization for when the current position matches the target replacement index. /// Replaces the first type with the new type and maintains the rest of the types. /// </summary> /// <typeparam name="array_template">The template of the array.</typeparam> /// <typeparam name="value_type">The original type being replaced.</typeparam> /// <typeparam name="other_types">The remaining types in the array.</typeparam> /// <typeparam name="helper_new_type">The new type to replace with.</typeparam> template<template<typename...> class array_template, typename value_type, typename... other_types, typename helper_new_type> struct replace_helper<replace_index, array_template<value_type, other_types...>, helper_new_type> { /// <summary> /// The resulting array after replacement, with the new type at the target position. /// </summary> using new_array = array_template<helper_new_type, other_types...>; }; /// <summary> /// Specialization for when the current position doesn't match the target replacement index. /// Keeps the current type and continues recursion for the rest of the array. /// </summary> /// <typeparam name="index">Current position in the array being processed.</typeparam> /// <typeparam name="array_template">The template of the array.</typeparam> /// <typeparam name="value_type">The current type to keep.</typeparam> /// <typeparam name="other_types">The remaining types in the array.</typeparam> /// <typeparam name="helper_new_type">The new type to insert at the target position.</typeparam> template<typename_array_size_type index, template<typename...> class array_template, typename value_type, typename... other_types, typename helper_new_type> struct replace_helper<index, array_template<value_type, other_types...>, helper_new_type> { /// <summary> /// The resulting array from keeping the current type and processing the rest of the array. /// Uses combine to prepend the current type to the array resulting from the recursive call. /// </summary> using new_array = typename combine<typename_array<value_type>, typename replace_helper<index + 1, array_template<other_types...>, helper_new_type>::new_array>::new_array; }; public: static_assert(replace_index < array_type::size, "Replace index must be less than the size of the array."); static_assert(replace_index >= 0, "Replace index must be non-negative."); /// <summary> /// The resulting array after replacing the type at the specified index. /// </summary> using new_array = typename replace_helper<0, array_type, new_type>::new_array; }; #endif // TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_REPLACE_H
#ifndef TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_REPLACE_PART_H #define TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_REPLACE_PART_H #include "base.hpp" #include "cut.hpp" /// <summary> /// Replaces a section of a typename_array with another type or array. /// </summary> /// <typeparam name="array_type">The original typename array to modify.</typeparam> /// <typeparam name="start">The starting index of the section to replace (inclusive).</typeparam> /// <typeparam name="end">The ending index of the section to replace (inclusive).</typeparam> /// <typeparam name="to_place_type">The type (must be wrapped into typename_array) or array to insert in place of the removed section.</typeparam> template<typename array_type, typename_array_size_type start, typename_array_size_type end, typename to_place_type> struct replace_part { /// <summary> /// The resulting array type after replacement. /// Combines three parts: the section before the replaced range, /// the inserted type, and the section after the replaced range. /// </summary> using new_array = typename combine< typename combine<typename cut<0, (start - 1), array_type>::new_array, to_place_type>::new_array, typename cut<end + 1, array_type::size - 1, array_type>::new_array>::new_array; }; #endif // TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_REPLACE_PART_H
#ifndef TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_SORT_H #define TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_SORT_H #include "base.hpp" #include "get.hpp" #include "cut.hpp" /// <summary> /// Sorts a typename array according to a specified predicate. /// </summary> /// <typeparam name="array_type">The typename array to be sorted.</typeparam> /// <typeparam name="predicate_template">Binary predicate template that determines sort order. Returns true if first type ordered before second.</typeparam> template<typename array_type, template<typename, typename> class predicate_template> struct sort { private: /// <summary> /// Helper structure to merge two sorted arrays into a single sorted array. /// </summary> /// <typeparam name="first_array_type">The first sorted array.</typeparam> /// <typeparam name="second_array_type">The second sorted array.</typeparam> template<typename first_array_type, typename second_array_type> struct combine_sorted_arrays; /// <summary> /// Specialization for when the second array is empty or invalid. /// </summary> /// <typeparam name="other_type">The type of the second (empty) array.</typeparam> /// <typeparam name="first_value_type">The first type in the first array.</typeparam> /// <typeparam name="first_other_types">Remaining types in the first array.</typeparam> /// <typeparam name="array_template">The template of the array.</typeparam> template<typename other_type, typename first_value_type, typename... first_other_types, template<typename...> class array_template> struct combine_sorted_arrays<array_template<first_value_type, first_other_types...>, other_type> { /// <summary> /// Returns the first array unchanged when the second array is empty. /// </summary> using new_array = array_template<first_value_type, first_other_types...>; }; /// <summary> /// Specialization for when the first array is empty or invalid. /// </summary> /// <typeparam name="other_type">The type of the first (empty) array.</typeparam> /// <typeparam name="second_value_type">The first type in the second array.</typeparam> /// <typeparam name="second_other_types">Remaining types in the second array.</typeparam> /// <typeparam name="array_template">The template of the array.</typeparam> template<typename other_type, typename second_value_type, typename... second_other_types, template<typename...> class array_template> struct combine_sorted_arrays<other_type, array_template<second_value_type, second_other_types...>> { /// <summary> /// Returns the second array unchanged when the first array is empty. /// </summary> using new_array = array_template<second_value_type, second_other_types...>; }; /// <summary> /// Specialization for combining two non-empty arrays by comparing their first elements. /// </summary> /// <typeparam name="first_value_type">The first type in the first array.</typeparam> /// <typeparam name="first_other_types">Remaining types in the first array.</typeparam> /// <typeparam name="second_value_type">The first type in the second array.</typeparam> /// <typeparam name="second_other_types">Remaining types in the second array.</typeparam> /// <typeparam name="array_template">The template of the array.</typeparam> template<typename first_value_type, typename... first_other_types, typename second_value_type, typename... second_other_types, template<typename...> class array_template> struct combine_sorted_arrays<array_template<first_value_type, first_other_types...>, array_template<second_value_type, second_other_types...>> { /// <summary> /// Determines if the first value should come before the second value according to the predicate. /// </summary> static constexpr bool is_value_before = predicate_template<first_value_type, second_value_type>::value; /// <summary> /// The type to be placed at the front of the merged array. /// </summary> using first_val = std::conditional_t<is_value_before, first_value_type, second_value_type>; /// <summary> /// The remaining arrays to be merged after removing the selected first element. /// </summary> using arrays = std::conditional_t< is_value_before, array_template<array_template<first_other_types...>, array_template<second_value_type, second_other_types...>>, array_template<array_template<first_value_type, first_other_types...>, array_template<second_other_types...>> >; /// <summary> /// The merged array combining the selected first element with the recursively merged remainder. /// </summary> using new_array = typename combine<array_template<first_val>, typename combine_sorted_arrays<typename get<0, arrays>::value, typename get<1, arrays>::value>::new_array >::new_array; }; /// <summary> /// Base helper structure for sorting arrays using merge sort algorithm. /// </summary> /// <typeparam name="first_type">First portion of the array to sort.</typeparam> /// <typeparam name="second_type">Second portion of the array to sort.</typeparam> template<typename first_type, typename second_type> struct sort_help { /// <summary> /// Default case returns an empty array. /// </summary> using new_array = typename_array<>; }; /// <summary> /// Specialization for when the first portion is empty. /// </summary> /// <typeparam name="first_type">Empty or invalid first portion.</typeparam> /// <typeparam name="value_type">First type in the second portion.</typeparam> /// <typeparam name="other_types">Remaining types in the second portion.</typeparam> /// <typeparam name="array_template">The template of the array.</typeparam> template<typename first_type, typename value_type, typename... other_types, template<typename...> class array_template> struct sort_help<first_type, array_template<value_type, other_types...>> { /// <summary> /// Returns the second portion unchanged when the first portion is empty. /// </summary> using new_array = array_template<value_type, other_types...>; }; /// <summary> /// Specialization for when the second portion is empty. /// </summary> /// <typeparam name="second_type">Empty or invalid second portion.</typeparam> /// <typeparam name="value_type">First type in the first portion.</typeparam> /// <typeparam name="other_types">Remaining types in the first portion.</typeparam> /// <typeparam name="array_template">The template of the array.</typeparam> template<typename second_type, typename value_type, typename... other_types, template<typename...> class array_template> struct sort_help<array_template<value_type, other_types...>, second_type> { /// <summary> /// Returns the first portion unchanged when the second portion is empty. /// </summary> using new_array = array_template<value_type, other_types...>; }; /// <summary> /// Specialization for sorting two single-element arrays. /// </summary> /// <typeparam name="first_other_type">The type in the first array.</typeparam> /// <typeparam name="second_other_type">The type in the second array.</typeparam> /// <typeparam name="array_template">The template of the array.</typeparam> template<typename first_other_type, typename second_other_type, template<typename> class array_template> struct sort_help<array_template<first_other_type>, array_template<second_other_type>> { /// <summary> /// The first single-element array. /// </summary> using first_array_type = array_template<first_other_type>; /// <summary> /// The second single-element array. /// </summary> using second_array_type = array_template<second_other_type>; /// <summary> /// Merges the two single-element arrays in sorted order. /// </summary> using new_array = typename combine_sorted_arrays<first_array_type, second_array_type>::new_array; }; /// <summary> /// Specialization for sorting two multi-element arrays using divide-and-conquer approach. /// </summary> /// <typeparam name="first_value_type">First type in the first array.</typeparam> /// <typeparam name="second_value_type">First type in the second array.</typeparam> /// <typeparam name="first_other_types">Remaining types in the first array.</typeparam> /// <typeparam name="second_other_types">Remaining types in the second array.</typeparam> /// <typeparam name="array_template">The template of the array.</typeparam> template<typename first_value_type, typename second_value_type, typename... first_other_types, typename... second_other_types, template<typename...> class array_template> struct sort_help<array_template<first_value_type, first_other_types...>, array_template<second_value_type, second_other_types...>> { /// <summary> /// The first array to be sorted. /// </summary> using first_array_type = array_template<first_value_type, first_other_types...>; /// <summary> /// The second array to be sorted. /// </summary> using second_array_type = array_template<second_value_type, second_other_types...>; /// <summary> /// Midpoint index of the first array. /// </summary> static constexpr typename_array_size_type first = first_array_type::size / 2; /// <summary> /// Midpoint index of the second array. /// </summary> static constexpr typename_array_size_type second = second_array_type::size / 2; /// <summary> /// Recursively sorts the first array by dividing it and merging the sorted halves. /// </summary> using first_half = typename sort_help< typename cut<0, first - 1, first_array_type>::new_array, typename cut<first, first_array_type::size - 1, first_array_type>::new_array >::new_array; /// <summary> /// Recursively sorts the second array by dividing it and merging the sorted halves. /// </summary> using second_half = typename sort_help< typename cut<0, second - 1, second_array_type>::new_array, typename cut<second, second_array_type::size - 1, second_array_type>::new_array >::new_array; /// <summary> /// Merges the two sorted arrays to produce the final sorted result. /// </summary> using new_array = typename combine_sorted_arrays<first_half, second_half>::new_array; }; /// <summary> /// Midpoint index of the input array. /// </summary> static constexpr typename_array_size_type half = array_type::size / 2; public: /// <summary> /// The sorted array produced by applying merge sort to the input array. /// </summary> using new_array = typename sort_help< typename cut<0, half - 1, array_type>::new_array, typename cut<half, array_type::size - 1, array_type>::new_array >::new_array; }; #endif // TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_SORT_H
#ifndef TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_STATIC_CALC_H #define TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_STATIC_CALC_H #include "base.hpp" #include "value-wrapper.hpp" #include "cut.hpp" #include "find-one-of.hpp" #include "left-to-right.hpp" #include "find-priority.hpp" #include "symbols-to-int.hpp" #include "get.hpp" #include "int-to-symbols.hpp" #include "replace-part.hpp" #include "typename-binder.hpp" /// <summary> /// Compiles and evaluates a mathematical expression at compile time using type-level computation. /// Supports basic arithmetic operations (+, -, *, /, %) and parentheses. /// Negative or fractional values are NOT supported and will break this. /// </summary> /// <typeparam name="symbols_types">A sequence of value types representing the characters in the expression.</typeparam> template<typename... symbols_types> struct static_calculator { private: /// <summary> /// Array of recognized operators and parentheses that can appear in expressions. /// </summary> using expressions_symbols_type = typename_array<value_wrapper<'('>, value_wrapper<'%'>, value_wrapper<'/'>, value_wrapper<'*'>, value_wrapper<'+'>, value_wrapper<'-'>, value_wrapper<')'>>; /// <summary> /// Enumeration of expression types to differentiate between regular expressions and parenthesized expressions. /// </summary> enum class expression_type { regular_expression, parentheses }; /// <summary> /// Finds the matching closing parenthesis for an opening parenthesis. /// </summary> /// <typeparam name="array_type">The array containing the expression.</typeparam> /// <typeparam name="start_index">The index of the opening parenthesis.</typeparam> template<typename array_type, typename_array_size_type start_index> struct find_last_closed_parentheses { private: /// <summary> /// Helper structure that tracks parenthesis nesting to find the matching closing parenthesis. /// </summary> /// <typeparam name="helper_array_type">The remaining portion of the array being processed.</typeparam> /// <typeparam name="parentheses_count">Current nesting level of parentheses.</typeparam> /// <typeparam name="index">Current position being examined.</typeparam> template<typename helper_array_type, typename_array_size_type parentheses_count, typename_array_size_type index> struct find_last_closed_parentheses_helper { /// <summary> /// The index where the search terminates. /// </summary> static constexpr typename_array_size_type indx = index; }; /// <summary> /// Recursive helper that processes each character and tracks parenthesis nesting. /// </summary> template<template<typename...> class array_template, typename... other_types, typename_array_size_type parentheses_count, typename_array_size_type index, char character> struct find_last_closed_parentheses_helper<array_template<value_wrapper<character>, other_types...>, parentheses_count, index> { /// <summary> /// Updates the parentheses count based on encountered parentheses. /// Increments for '(', decrements for ')', otherwise no change. /// </summary> static constexpr typename_array_size_type parentheses_count_new = (character == '(') ? (parentheses_count + 1) : (character == ')') ? (parentheses_count - 1) : parentheses_count; /// <summary> /// The index of the matching closing parenthesis, or continues the search. /// Returns the current index if parentheses_count becomes zero (matching parenthesis found). /// </summary> static constexpr typename_array_size_type indx = (parentheses_count == 0) ? index : find_last_closed_parentheses_helper<array_template<other_types...>, parentheses_count_new, (index + 1)>::indx; }; public: /// <summary> /// The index of the closing parenthesis that matches the opening parenthesis at start_index. /// </summary> static constexpr typename_array_size_type index = find_last_closed_parentheses_helper<array_type, 1, start_index>::indx; }; /// <summary> /// Determines the boundaries of an expression around an operator. /// For regular expressions, finds the complete left and right operands. /// </summary> /// <typeparam name="character">The operator character.</typeparam> /// <typeparam name="array_type">The array containing the expression.</typeparam> /// <typeparam name="index">The index of the operator.</typeparam> template<char character, typename array_type, typename_array_size_type index> struct find_boundaries { /// <summary> /// The right half of the expression after the operator. /// </summary> using expression_right_half_type = typename cut<(index + 1), (array_type::size - 1), array_type>::new_array; /// <summary> /// The index of the next operator in the right half, or -1 if none exists. /// </summary> static constexpr typename_array_size_type right_half_end = find_one_of<expression_right_half_type, expressions_symbols_type>::index; /// <summary> /// Type representing the true end index of the right operand. /// If no more operators are found, uses the end of the array. /// </summary> using true_right_half_end_type = std::conditional_t<(right_half_end == -1), value_wrapper<(array_type::size - 1)>, value_wrapper<(index + right_half_end)>>; /// <summary> /// The end index of the right operand. /// </summary> static constexpr typename_array_size_type true_right_half_end = true_right_half_end_type::get_value; /// <summary> /// The left half of the expression before the operator, reversed for search. /// </summary> using expression_left_half_type = typename left_to_right<typename cut<0, (index - 1), array_type>::new_array>::new_array; /// <summary> /// The index of the previous operator in the left half, or -1 if none exists. /// </summary> static constexpr typename_array_size_type left_half_end = find_one_of<expression_left_half_type, expressions_symbols_type>::index; /// <summary> /// Type representing the true start index of the left operand. /// If no previous operators are found, uses the start of the array. /// </summary> using expression_true_left_half_end_type = std::conditional_t<(left_half_end == -1), value_wrapper<static_cast<typename_array_size_type>(0)>, value_wrapper<index - left_half_end>>; /// <summary> /// The start index of the left operand. /// </summary> static constexpr typename_array_size_type true_left_half_end = expression_true_left_half_end_type::get_value; /// <summary> /// Array containing information about the expression boundaries: /// [expression type, left boundary, right boundary, operator index] /// </summary> using expression_boundaries_type = typename_array< value_wrapper<expression_type::regular_expression>, value_wrapper<true_left_half_end>, value_wrapper<true_right_half_end>, value_wrapper<index> >; }; /// <summary> /// Specialization for parenthesized expressions, which have different boundary rules. /// </summary> /// <typeparam name="array_type">The array containing the expression.</typeparam> /// <typeparam name="index">The index of the opening parenthesis.</typeparam> template<typename array_type, typename_array_size_type index> struct find_boundaries<'(', array_type, index> { /// <summary> /// The right half of the expression after the opening parenthesis. /// </summary> using right_half_of_expression = typename cut<(index + 1), (array_type::size - 1), array_type>::new_array; /// <summary> /// The index of the matching closing parenthesis. /// </summary> static constexpr typename_array_size_type last_closed_parentheses = find_last_closed_parentheses<right_half_of_expression, index>::index; /// <summary> /// Array containing information about the parenthesized expression boundaries: /// [expression type, opening parenthesis index, closing parenthesis index, opening parenthesis index] /// </summary> using expression_boundaries_type = typename_array< value_wrapper<expression_type::parentheses>, value_wrapper<index>, value_wrapper<last_closed_parentheses>, value_wrapper<index>>; }; /// <summary> /// Finds the expression with the highest operator precedence to evaluate next. /// </summary> /// <typeparam name="helper_symbols_types">The symbols in the expression.</typeparam> template<typename... helper_symbols_types> struct find_expression_with_highest_priority { /// <summary> /// The index of the highest priority operator in the expression. /// </summary> static constexpr typename_array_size_type highest_priority_symbol = find_priority<typename_array<helper_symbols_types...>, expressions_symbols_type>::index; /// <summary> /// The type of the highest priority operator. /// </summary> using symbol = typename get<highest_priority_symbol, typename_array<helper_symbols_types...>>::value; /// <summary> /// Array containing the expression boundaries and the operator symbol. /// </summary> using array = typename combine< typename find_boundaries<symbol::get_value, typename_array<helper_symbols_types...>, highest_priority_symbol>::expression_boundaries_type, typename_array<symbol> >::new_array; }; /// <summary> /// Calculates the result of a simple (atomic) expression based on its type and operands. /// </summary> /// <typeparam name="ex_type">The type of the expression (regular or parenthesized).</typeparam> /// <typeparam name="simple_expression_info_type">Information about the expression boundaries.</typeparam> /// <typeparam name="array_type">The array containing the expression.</typeparam> template<expression_type ex_type, typename simple_expression_info_type, typename array_type> struct calculate_simple_expression { private: /// <summary> /// Helper structure for performing different calculations based on operator. /// </summary> /// <typeparam name="symbol">The operator character.</typeparam> /// <typeparam name="left_part_type">The left operand.</typeparam> /// <typeparam name="right_part_type">The right operand.</typeparam> template<char symbol, typename left_part_type, typename right_part_type> struct perform; /// <summary> /// Specialization for the modulo operator (%). /// </summary> template<typename left_part_type, typename right_part_type> struct perform<'%', left_part_type, right_part_type> { /// <summary> /// The result of the modulo operation. /// </summary> static constexpr typename_array_size_type value = left_part_type::template acquire<symbols_to_int>::result % right_part_type::template acquire<symbols_to_int>::result; }; /// <summary> /// Specialization for the multiplication operator (*). /// </summary> template<typename left_part_type, typename right_part_type> struct perform<'*', left_part_type, right_part_type> { /// <summary> /// The result of the multiplication operation. /// </summary> static constexpr typename_array_size_type value = left_part_type::template acquire<symbols_to_int>::result * right_part_type::template acquire<symbols_to_int>::result; }; /// <summary> /// Specialization for the division operator (/). /// </summary> template<typename left_part_type, typename right_part_type> struct perform<'/', left_part_type, right_part_type> { /// <summary> /// The result of the division operation. /// </summary> static constexpr typename_array_size_type value = left_part_type::template acquire<symbols_to_int>::result / right_part_type::template acquire<symbols_to_int>::result; }; /// <summary> /// Specialization for the addition operator (+). /// </summary> template<typename left_part_type, typename right_part_type> struct perform<'+', left_part_type, right_part_type> { /// <summary> /// The result of the addition operation. /// </summary> static constexpr typename_array_size_type value = left_part_type::template acquire<symbols_to_int>::result + right_part_type::template acquire<symbols_to_int>::result; }; /// <summary> /// Specialization for the subtraction operator (-). /// </summary> template<typename left_part_type, typename right_part_type> struct perform<'-', left_part_type, right_part_type> { /// <summary> /// The result of the subtraction operation. /// </summary> static constexpr typename_array_size_type value = left_part_type::template acquire<symbols_to_int>::result - right_part_type::template acquire<symbols_to_int>::result; }; public: /// <summary> /// The start index of the expression. /// </summary> using start_type = typename get<1, simple_expression_info_type>::value; /// <summary> /// The end index of the expression. /// </summary> using end_type = typename get<2, simple_expression_info_type>::value; /// <summary> /// The index of the operator. /// </summary> using expression_index_type = typename get<3, simple_expression_info_type>::value; /// <summary> /// The operator symbol. /// </summary> using expression_character_type = typename get<4, simple_expression_info_type>::value; /// <summary> /// The result of the calculation converted back to a sequence of digit symbols. /// </summary> using calculated_symbols_type = typename int_to_symbols<perform<expression_character_type::get_value, typename cut<start_type::get_value, (expression_index_type::get_value - 1), array_type>::new_array, typename cut<(expression_index_type::get_value + 1), end_type::get_value, array_type>::new_array>::value >::array; }; /// <summary> /// Main recursion helper for evaluating expressions. /// Continues recursion as long as operators remain in the expression. /// </summary> /// <typeparam name="is_changeable_type">Flag indicating if the expression still contains operators.</typeparam> /// <typeparam name="helper_symbols_types">The symbols in the expression.</typeparam> template<typename is_changeable_type, typename... helper_symbols_types> struct static_calculator_helper { /// <summary> /// The current expression as an array. /// </summary> using array_type = typename_array<helper_symbols_types...>; /// <summary> /// Information about the highest priority expression to evaluate next. /// </summary> using simple_expression_info_type = typename find_expression_with_highest_priority<helper_symbols_types...>::array; /// <summary> /// The type of the expression (regular or parenthesized). /// </summary> using expression_type = typename get<0, simple_expression_info_type>::value; /// <summary> /// The start index of the expression. /// </summary> using start_type = typename get<1, simple_expression_info_type>::value; /// <summary> /// The end index of the expression. /// </summary> using end_type = typename get<2, simple_expression_info_type>::value; /// <summary> /// The result symbols of calculating the current expression. /// </summary> using new_symbols_type = typename calculate_simple_expression<expression_type::get_value, simple_expression_info_type, array_type>::calculated_symbols_type; /// <summary> /// The array with the calculated expression replaced. /// </summary> using new_array_type = typename replace_part<array_type, start_type::get_value, end_type::get_value, new_symbols_type>::new_array; /// <summary> /// Binder for continuing recursion if operators remain. /// </summary> using binder_type = typename_binder<static_calculator_helper, value_wrapper<(find_one_of<new_array_type, expressions_symbols_type>::index != -1)>>; /// <summary> /// The value of the expression after recursive evaluation. /// </summary> static constexpr typename_array_size_type value = new_array_type::template acquire<binder_type::template bind>::value; }; /// <summary> /// Terminal case for recursion when no operators remain. /// Converts the remaining digit symbols to an integer. /// </summary> template<typename... helper_symbols_types> struct static_calculator_helper<value_wrapper<false>, helper_symbols_types...> { /// <summary> /// The final value of the expression. /// </summary> static constexpr typename_array_size_type value = symbols_to_int<helper_symbols_types...>::result; }; /// <summary> /// Specialization for calculating parenthesized expressions. /// Handles the recursion into evaluating the expression inside parentheses. /// </summary> template<typename simple_expression_info_type, typename array_type> struct calculate_simple_expression<expression_type::parentheses, simple_expression_info_type, array_type> { /// <summary> /// The index of the opening parenthesis. /// </summary> using start_type = typename get<1, simple_expression_info_type>::value; /// <summary> /// The index of the closing parenthesis. /// </summary> using end_type = typename get<2, simple_expression_info_type>::value; /// <summary> /// The expression inside the parentheses. /// </summary> using in_parentheses_type = typename cut<(start_type::get_value + 1), (end_type::get_value - 1), array_type>::new_array; /// <summary> /// Binder for recursively evaluating the parenthesized expression. /// </summary> using binder_type = typename_binder<static_calculator_helper, value_wrapper<(find_one_of<in_parentheses_type, expressions_symbols_type>::index != -1)>>; /// <summary> /// The result of evaluating the parenthesized expression, converted to digit symbols. /// </summary> using calculated_symbols_type = typename int_to_symbols<in_parentheses_type::template acquire<binder_type::template bind>::value>::array; }; public: /// <summary> /// The final result of evaluating the mathematical expression. /// </summary> static constexpr typename_array_size_type result = static_calculator_helper<value_wrapper<(find_one_of<typename_array<symbols_types...>, expressions_symbols_type>::index != -1)>, symbols_types...>::value; }; #endif // TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_STATIC_CALC_H
#ifndef TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_STATIC_POW_H #define TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_STATIC_POW_H #include "base.hpp" /// <summary> /// Calculates the power of a value at compile time. /// </summary> /// <typeparam name="value">The base value to be raised to a power.</typeparam> /// <typeparam name="counter">The exponent to raise the base value to.</typeparam> template<typename_array_size_type value, typename_array_size_type counter> struct static_pow { private: /// <summary> /// Helper structure for calculating power using recursive template instantiation. /// </summary> /// <typeparam name="helper_value">The base value being raised to a power.</typeparam> /// <typeparam name="helper_counter">The remaining exponent to process.</typeparam> template<typename_array_size_type helper_value, typename_array_size_type helper_counter> struct static_pow_helper { /// <summary> /// Recursively calculates the power by multiplying the base value by the result of the next lower power. /// </summary> static constexpr typename_array_size_type result = helper_value * static_pow<helper_value, (helper_counter - 1)>::result; }; /// <summary> /// Specialization for the base case when exponent is zero. /// Any number raised to the power of zero equals one. /// </summary> /// <typeparam name="helper_value">The base value (not used in calculation when exponent is zero).</typeparam> template<typename_array_size_type helper_value> struct static_pow_helper<helper_value, 0> { /// <summary> /// The result of any number raised to the power of zero is one. /// </summary> static constexpr typename_array_size_type result = 1; }; public: static_assert(counter >= 0, "Exponent must be non-negative."); /// <summary> /// The final result of raising the base value to the specified power. /// </summary> static constexpr typename_array_size_type result = static_pow_helper<value, counter>::result; }; #endif // TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_STATIC_POW_H
#ifndef TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_SUM_H #define TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_SUM_H #include "base.hpp" /// <summary> /// Calculates the sum of values associated with each type in a typename_array by applying a functor. /// </summary> /// <typeparam name="array_type">The typename array containing the types to process.</typeparam> /// <typeparam name="functor_template">The functor template that extracts a value from each type.</typeparam> /// <typeparam name="return_type">The type of the summed result.</typeparam> template<typename array_type, template<typename> class functor_template, typename return_type> struct sum { private: /// <summary> /// Base helper structure for summing values. /// Provides the final sum when recursion is complete. /// </summary> /// <typeparam name="helper_array_type">Array or remaining portion being processed.</typeparam> /// <typeparam name="helper_functor_template">The functor template applied to each type.</typeparam> template<typename helper_array_type, template<typename> class helper_functor_template> struct sum_helper { /// <summary> /// The value for an empty array (base case). /// </summary> static constexpr return_type new_value{ 0 }; }; /// <summary> /// Specialization for when the array contains a single type. /// Extracts the value from that type using the functor. /// </summary> /// <typeparam name="array_template">The template of the array.</typeparam> /// <typeparam name="value_type">The single type in the array.</typeparam> /// <typeparam name="helper_functor_template">The functor template applied to the type.</typeparam> template<template<typename> class array_template, typename value_type, template<typename> class helper_functor_template> struct sum_helper<array_template<value_type>, helper_functor_template> { /// <summary> /// The value extracted from the single type. /// </summary> static constexpr return_type new_value = helper_functor_template<value_type>::value; }; /// <summary> /// Specialization for when the array contains multiple types. /// Applies the functor to the first type and recursively processes the rest. /// </summary> /// <typeparam name="array_template">The template of the array.</typeparam> /// <typeparam name="value_type">The current type being processed.</typeparam> /// <typeparam name="other_types">Remaining types in the array.</typeparam> /// <typeparam name="helper_functor_template">The functor template applied to each type.</typeparam> template<template<typename...> class array_template, typename value_type, typename... other_types, template<typename> class helper_functor_template> struct sum_helper<array_template<value_type, other_types...>, helper_functor_template> { /// <summary> /// The sum of the value from the current type plus the sum of values from remaining types. /// </summary> static constexpr decltype(auto) new_value = helper_functor_template<value_type>::value + sum_helper<array_template<other_types...>, helper_functor_template>::new_value; }; public: /// <summary> /// The total sum of values extracted from all types in the array. /// </summary> static constexpr decltype(auto) new_value = sum_helper<array_type, functor_template>::new_value; }; #endif // TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_SUM_H
#ifndef TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_SYMBOLS_TO_INT_H #define TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_SYMBOLS_TO_INT_H #include "base.hpp" #include "get.hpp" #include "erase.hpp" #include "value-wrapper.hpp" #include "static-pow.hpp" /// <summary> /// Converts a sequence of symbol types into an integer value. /// Handles negative numbers by checking if the first symbol is a minus sign. /// </summary> /// <typeparam name="symbols_types">The sequence of symbol types to convert to an integer.</typeparam> template<typename... symbols_types> struct symbols_to_int { private: /// <summary> /// Helper structure for the recursive conversion of symbols to integer. /// </summary> /// <typeparam name="helper_symbols_types">Symbol types being processed.</typeparam> template<typename... helper_symbols_types> struct symbols_to_int_helper; /// <summary> /// Recursive specialization that processes one symbol at a time. /// Multiplies the current symbol's value by the appropriate power of 10 based on position. /// </summary> /// <typeparam name="symbol_type">Current symbol being processed.</typeparam> /// <typeparam name="helper_symbols_types">Remaining symbols to process.</typeparam> template<typename symbol_type, typename... helper_symbols_types> struct symbols_to_int_helper<symbol_type, helper_symbols_types...> { /// <summary> /// Converts the current digit and adds it to the recursively processed remainder. /// </summary> static constexpr typename_array_size_type result = ((symbol_type::get_value - '0') * static_pow<10, sizeof...(helper_symbols_types)>::result) + symbols_to_int_helper<helper_symbols_types...>::result; static_assert(symbol_type::get_value >= '0' && symbol_type::get_value <= '9', "All symbols must be digits (0-9)."); }; /// <summary> /// Base case specialization for the last symbol in the sequence. /// </summary> /// <typeparam name="symbol_type">The last symbol to process.</typeparam> template<typename symbol_type> struct symbols_to_int_helper<symbol_type> { /// <summary> /// Converts the last digit to its integer value. /// </summary> static constexpr typename_array_size_type result = (symbol_type::get_value - '0'); static_assert(symbol_type::get_value >= '0' && symbol_type::get_value <= '9', "All symbols must be digits (0-9)."); }; /// <summary> /// The first symbol in the sequence, used to check for negative numbers. /// </summary> using first_symbol_type = typename get<0, typename_array<symbols_types...>>::value; /// <summary> /// Creates a reduced symbol type which: /// 1. Removes the minus sign if present /// 2. Includes a multiplier (-1 for negative numbers, 1 for positive) /// </summary> using reduced_symbols_type = std::conditional_t< first_symbol_type::get_value == '-', typename_array<typename erase<0, typename_array<symbols_types...>>::new_array, value_wrapper<-1>>, typename_array<typename_array<symbols_types...>, value_wrapper<1>> >; public: /// <summary> /// The final integer result after converting the symbol sequence. /// Accounts for sign by multiplying the absolute value by the sign multiplier. /// </summary> static constexpr typename_array_size_type result = get<0, reduced_symbols_type>::value::template acquire<symbols_to_int_helper>::result * get<1, reduced_symbols_type>::value::get_value; }; #endif // TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_SYMBOLS_TO_INT_H
#ifndef TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_TYPENAME_BINDER_H #define TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_TYPENAME_BINDER_H #include "base.hpp" #include "replace.hpp" #include "insert.hpp" #include "find.hpp" #include "left-to-right.hpp" #include "get.hpp" /// <summary> /// A placeholder type used to mark positions where types should be inserted. /// </summary> /// <typeparam name="index">The index of the placeholder for reference.</typeparam> template<typename_array_size_type index> struct binder_placeholder { static constexpr typename_array_size_type get_index = index; }; /// <summary> /// A template binder that allows for flexible creation of templates with placeholder substitution. /// Enables the creation of templates where types are inserted at specific marked positions. /// </summary> /// <typeparam name="target_template">The template class to be instantiated after binding.</typeparam> /// <typeparam name="other_types">Initial types that may contain placeholders.</typeparam> template<template<typename...> class target_template, typename... other_types> struct typename_binder { private: /// <summary> /// Helper for dispatching between replacement and insertion operations. /// Used when a placeholder is found at a specific index. /// </summary> /// <typeparam name="index">The index where the placeholder was found.</typeparam> /// <typeparam name="array_type">The array being processed.</typeparam> /// <typeparam name="value_type">The value to insert or replace with.</typeparam> template<typename_array_size_type index, typename array_type, typename value_type> struct dispatch { /// <summary> /// The array after replacement of the placeholder at the specified index. /// </summary> using value = typename replace<index, array_type, value_type>::new_array; }; /// <summary> /// Specialization for when no placeholder is found (npos). /// In this case, append the value to the end of the array. /// </summary> /// <typeparam name="array_type">The array being processed.</typeparam> /// <typeparam name="value_type">The value to append.</typeparam> template<typename array_type, typename value_type> struct dispatch<npos, array_type, value_type> { /// <summary> /// The array after appending the value to the end. /// Notice that elements are added in the order they appear in "additional_other". /// That's why we need to use sizeof... (other_types). /// </summary> using value = typename insert<sizeof... (other_types), array_type, value_type>::new_array; }; /// <summary> /// Recursive helper for binding placeholders to actual types. /// Processes each placeholder by finding and replacing it with the corresponding type. /// </summary> /// <typeparam name="index">Current placeholder index being processed.</typeparam> /// <typeparam name="end">Last placeholder index to process.</typeparam> /// <typeparam name="array_type">Array containing the types to be bound.</typeparam> template<typename_array_size_type index, typename_array_size_type end, typename array_type> struct bind_helper { /// <summary> /// Recursively process the next placeholder. /// </summary> using temporary = typename bind_helper<index + 1, end, array_type>::bind; /// <summary> /// Find and replace the current placeholder with its corresponding type. /// </summary> using bind = typename dispatch< find<temporary, binder_placeholder<index>>::index, temporary, typename get<index, array_type>::value >::value; }; /// <summary> /// Base case for bind_helper recursion - processes the final placeholder. /// </summary> /// <typeparam name="end">Index of the final placeholder.</typeparam> /// <typeparam name="array_type">Array containing the types to be bound.</typeparam> template<typename_array_size_type end, typename array_type> struct bind_helper<end, end, array_type> { /// <summary> /// Process the final placeholder directly using the initial template. /// </summary> using bind = typename dispatch< find<typename_array<other_types...>, binder_placeholder<end>>::index, typename_array<other_types...>, typename get<end, array_type>::value >::value; }; public: /// <summary> /// Binds the placeholders in the template with the provided types. /// This creates a new template instance with placeholders replaced by actual types. /// </summary> /// <typeparam name="additional_other">The types to bind to the placeholders.</typeparam> template<typename... additional_other> using bind = typename bind_helper< 0, typename_array<additional_other...>::size - 1, typename_array<additional_other...> >::bind::template acquire<target_template>; }; #endif // TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_TYPENAME_BINDER_H
#ifndef TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_UNIQUE_ADD_H #define TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_UNIQUE_ADD_H #include "base.hpp" #include "insert.hpp" #include "find.hpp" /// <summary> /// Adds a new type to a typename_array only if it doesn't already exist in the array. /// </summary> /// <typeparam name="index">The position at which to insert the new type if needed.</typeparam> /// <typeparam name="array_type">The typename array to potentially modify.</typeparam> /// <typeparam name="new_value_type">The new type to add if not already present.</typeparam> template<typename_array_size_type index, typename array_type, typename new_value_type> struct unique_add { private: /// <summary> /// Base helper structure for the unique_add operation. /// </summary> /// <typeparam name="found">The index where the type was found, or npos if not found.</typeparam> /// <typeparam name="helper_array_type">The array being processed.</typeparam> /// <typeparam name="helper_new_value_type">The type to potentially add.</typeparam> template<typename_array_size_type found, typename helper_array_type, typename helper_new_value_type> struct unique_add_helper { /// <summary> /// When the type is already found in the array, return the original array unchanged. /// </summary> using value = helper_array_type; }; /// <summary> /// Specialization for when the type is not found in the array. /// </summary> /// <typeparam name="helper_array_type">The array being processed.</typeparam> /// <typeparam name="helper_new_value_type">The type to add.</typeparam> template<typename helper_array_type, typename helper_new_value_type> struct unique_add_helper<npos, helper_array_type, helper_new_value_type> { /// <summary> /// When the type is not found, insert it at the specified index. /// </summary> using value = typename insert<index, helper_array_type, helper_new_value_type>::new_array; }; public: /// <summary> /// The resulting array after the unique add operation. /// Contains the new type only if it wasn't already present. /// </summary> using new_array = typename unique_add_helper<find<array_type, new_value_type>::index, array_type, new_value_type>::value; }; #endif // TYPENAME_ARRAY_TYPENAME_ARRAY_PRIMITIVES_UNIQUE_ADD_H
#ifndef TYPENAME_ARRAY_VALUE_H #define TYPENAME_ARRAY_VALUE_H #include "base.hpp" /// <summary> /// Wraps a compile-time value of any type in a type context. /// This allows non-type template parameters to be used in typename arrays. /// </summary> /// <typeparam name="value">The compile-time value to wrap in a type.</typeparam> template<auto value> struct value_wrapper { /// <summary> /// The wrapped value, accessible as a static constant. /// </summary> static constexpr decltype(value) get_value = value; }; #endif // TYPENAME_ARRAY_VALUE_H

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue