From 36d1c72990d2d654cc45d988bc1a7cb76d8ab904 Mon Sep 17 00:00:00 2001 From: Braxton Salyer Date: Sun, 28 Jan 2024 22:51:35 -0600 Subject: [PATCH] Add mpl::Value meta-programming type; comparison operator support detection type traits and concepts; general operator support detection type traits and concepts; std supplemental type traits and concepts; --- .clang-format | 2 +- CMakeLists.txt | 10 +- include/hyperion/mpl/algorithms.h | 7 + include/hyperion/mpl/concepts.h | 8 + include/hyperion/mpl/concepts/comparable.h | 113 ++++++ include/hyperion/mpl/concepts/operator_able.h | 80 ++++ .../hyperion/mpl/concepts/std_supplemental.h | 41 ++ include/hyperion/mpl/type_traits.h | 8 + .../hyperion/mpl/type_traits/is_comparable.h | 227 +++++++++++ .../mpl/type_traits/is_operator_able.h | 302 ++++++++++++++ .../mpl/type_traits/std_supplemental.h | 45 +++ include/hyperion/mpl/value.h | 379 +++++++++++++++++- src/main.cpp | 11 +- xmake.lua | 23 +- 14 files changed, 1236 insertions(+), 20 deletions(-) create mode 100644 include/hyperion/mpl/concepts/comparable.h create mode 100644 include/hyperion/mpl/concepts/operator_able.h create mode 100644 include/hyperion/mpl/concepts/std_supplemental.h create mode 100644 include/hyperion/mpl/type_traits/is_comparable.h create mode 100644 include/hyperion/mpl/type_traits/is_operator_able.h create mode 100644 include/hyperion/mpl/type_traits/std_supplemental.h diff --git a/.clang-format b/.clang-format index ab8d39f..b0e9d66 100644 --- a/.clang-format +++ b/.clang-format @@ -84,7 +84,7 @@ IndentCaseLabels: true IndentExternBlock: Indent IndentGotoLabels: true IndentPPDirectives: BeforeHash -IndentRequires: false +IndentRequiresClause: true IndentWidth: 4 IndentWrappedFunctionNames: false KeepEmptyLinesAtTheStartOfBlocks: true diff --git a/CMakeLists.txt b/CMakeLists.txt index b13cf5d..40f0e75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,13 +48,19 @@ set(HYPERION_PLATFORM_INCLUDE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/include/hyperion" ) set(HYPERION_PLATFORM_HEADERS - "${HYPERION_PLATFORM_INCLUDE_PATH}/mpl/concepts.h" "${HYPERION_PLATFORM_INCLUDE_PATH}/mpl/index.h" "${HYPERION_PLATFORM_INCLUDE_PATH}/mpl/list.h" - "${HYPERION_PLATFORM_INCLUDE_PATH}/mpl/type_traits.h" "${HYPERION_PLATFORM_INCLUDE_PATH}/mpl/value.h" "${HYPERION_PLATFORM_INCLUDE_PATH}/mpl/algorithms.h" "${HYPERION_PLATFORM_INCLUDE_PATH}/mpl/algorithms/all_of.h" + "${HYPERION_PLATFORM_INCLUDE_PATH}/mpl/concepts.h" + "${HYPERION_PLATFORM_INCLUDE_PATH}/mpl/concepts/comparable.h" + "${HYPERION_PLATFORM_INCLUDE_PATH}/mpl/concepts/operator_able.h" + "${HYPERION_PLATFORM_INCLUDE_PATH}/mpl/concepts/std_supplemental.h" + "${HYPERION_PLATFORM_INCLUDE_PATH}/mpl/type_traits.h" + "${HYPERION_PLATFORM_INCLUDE_PATH}/mpl/type_traits/is_comparable.h" + "${HYPERION_PLATFORM_INCLUDE_PATH}/mpl/type_traits/is_operator_able.h" + "${HYPERION_PLATFORM_INCLUDE_PATH}/mpl/type_traits/std_supplemental.h" ) add_library(hyperion_mpl INTERFACE) diff --git a/include/hyperion/mpl/algorithms.h b/include/hyperion/mpl/algorithms.h index 8b7da54..a36ebd1 100644 --- a/include/hyperion/mpl/algorithms.h +++ b/include/hyperion/mpl/algorithms.h @@ -24,3 +24,10 @@ /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE /// SOFTWARE. + +#ifndef HYPERION_MPL_ALGORITHMS_H +#define HYPERION_MPL_ALGORITHMS_H + +#include + +#endif // HYPERION_MPL_ALGORITHMS_H diff --git a/include/hyperion/mpl/concepts.h b/include/hyperion/mpl/concepts.h index 598cb0e..93b9aa8 100644 --- a/include/hyperion/mpl/concepts.h +++ b/include/hyperion/mpl/concepts.h @@ -25,3 +25,11 @@ /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE /// SOFTWARE. +#ifndef HYPERION_MPL_CONCEPTS_H +#define HYPERION_MPL_CONCEPTS_H + +#include +#include +#include + +#endif // HYPERION_MPL_CONCEPTS_H diff --git a/include/hyperion/mpl/concepts/comparable.h b/include/hyperion/mpl/concepts/comparable.h new file mode 100644 index 0000000..a079e7a --- /dev/null +++ b/include/hyperion/mpl/concepts/comparable.h @@ -0,0 +1,113 @@ +/// @file comparable.h +/// @author Braxton Salyer +/// @brief Meta-programming C++20 concepts to determine if two types are comparable +/// in various ways +/// @version 0.1 +/// @date 2024-01-27 +/// +/// MIT License +/// @copyright Copyright (c) 2024 Braxton Salyer +/// +/// Permission is hereby granted, free of charge, to any person obtaining a copy +/// of this software and associated documentation files (the "Software"), to +/// deal in the Software without restriction, including without limitation the +/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +/// sell copies of the Software, and to permit persons to whom the Software is +/// furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +/// IN THE SOFTWARE. + +#ifndef HYPERION_MPL_CONCEPTS_COMPARABLE_H +#define HYPERION_MPL_CONCEPTS_COMPARABLE_H + +#include + +namespace hyperion::mpl::concepts { + + template + concept EqualityComparable = type_traits::is_equality_comparable_v; + + template + concept InequalityComparable = type_traits::is_inequality_comparable_v; + + template + concept LessThanComparable = type_traits::is_less_than_comparable_v; + + template + concept LessThanOrEqualComparable = type_traits::is_less_than_or_equal_comparable_v; + + template + concept GreaterThanComparable = type_traits::is_greater_than_comparable_v; + + template + concept GreaterThanOrEqualComparable + = type_traits::is_greater_than_or_equal_comparable_v; + + template + concept ThreeWayComparable = type_traits::is_three_way_comparable_v; + + namespace _test { + + struct not_comparable { }; + + static_assert(EqualityComparable, + "hyperion::mpl::concepts::EqualityComparable test case 1 failing"); + static_assert(EqualityComparable, + "hyperion::mpl::concepts::EqualityComparable test case 2 failing"); + static_assert(!EqualityComparable, + "hyperion::mpl::concepts::EqualityComparable test case 3 failing"); + + static_assert(InequalityComparable, + "hyperion::mpl::concepts::InequalityComparable test case 1 failing"); + static_assert(InequalityComparable, + "hyperion::mpl::concepts::InequalityComparable test case 2 failing"); + static_assert(!InequalityComparable, + "hyperion::mpl::concepts::InequalityComparable test case 3 failing"); + + static_assert(LessThanComparable, + "hyperion::mpl::concepts::LessThanComparable test case 1 failing"); + static_assert(LessThanComparable, + "hyperion::mpl::concepts::LessThanComparable test case 2 failing"); + static_assert(!LessThanComparable, + "hyperion::mpl::concepts::LessThanComparable test case 3 failing"); + + static_assert(LessThanOrEqualComparable, + "hyperion::mpl::concepts::LessThanOrEqualComparable test case 1 failing"); + static_assert(LessThanOrEqualComparable, + "hyperion::mpl::concepts::LessThanOrEqualComparable test case 2 failing"); + static_assert(!LessThanOrEqualComparable, + "hyperion::mpl::concepts::LessThanOrEqualComparable test case 3 failing"); + + static_assert(GreaterThanComparable, + "hyperion::mpl::concepts::GreaterThanComparable test case 1 failing"); + static_assert(GreaterThanComparable, + "hyperion::mpl::concepts::GreaterThanComparable test case 2 failing"); + static_assert(!GreaterThanComparable, + "hyperion::mpl::concepts::GreaterThanComparable test case 3 failing"); + + static_assert(GreaterThanOrEqualComparable, + "hyperion::mpl::concepts::GreaterThanOrEqualComparable test case 1 failing"); + static_assert(GreaterThanOrEqualComparable, + "hyperion::mpl::concepts::GreaterThanOrEqualComparable test case 2 failing"); + static_assert(!GreaterThanOrEqualComparable, + "hyperion::mpl::concepts::GreaterThanOrEqualComparable test case 3 failing"); + + static_assert(ThreeWayComparable, + "hyperion::mpl::concepts::ThreeWayComparable test case 1 failing"); + static_assert(ThreeWayComparable, + "hyperion::mpl::concepts::ThreeWayComparable test case 2 failing"); + static_assert(!ThreeWayComparable, + "hyperion::mpl::concepts::ThreeWayComparable test case 3 failing"); + } // namespace _test +} // namespace hyperion::mpl::concepts + +#endif // HYPERION_MPL_CONCEPTS_IS_COMPARABLE_H diff --git a/include/hyperion/mpl/concepts/operator_able.h b/include/hyperion/mpl/concepts/operator_able.h new file mode 100644 index 0000000..78889f0 --- /dev/null +++ b/include/hyperion/mpl/concepts/operator_able.h @@ -0,0 +1,80 @@ +/// @file operator_able.h +/// @author Braxton Salyer +/// @brief Meta-programming C++20 concept definitions to determine if a type +/// (or types) support an operator +/// @version 0.1 +/// @date 2024-01-27 +/// +/// MIT License +/// @copyright Copyright (c) 2024 Braxton Salyer +/// +/// Permission is hereby granted, free of charge, to any person obtaining a copy +/// of this software and associated documentation files (the "Software"), to +/// deal in the Software without restriction, including without limitation the +/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +/// sell copies of the Software, and to permit persons to whom the Software is +/// furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +/// IN THE SOFTWARE. + +#ifndef HYPERION_MPL_CONCEPTS_OPERATOR_ABLE_H +#define HYPERION_MPL_CONCEPTS_OPERATOR_ABLE_H + +#include + +namespace hyperion::mpl::concepts { + + template + concept UnaryPlusable = type_traits::is_unary_plusable_v; + + template + concept UnaryMinusable = type_traits::is_unary_minusable_v; + + template + concept BinaryNotable = type_traits::is_binary_notable_v; + + template + concept BooleanNotable = type_traits::is_boolean_notable_v; + + template + concept Addressable = type_traits::is_addressable_v; + + template + concept Arrowable = type_traits::is_arrowable_v; + + template + concept Addable = type_traits::is_addable_v; + + template + concept Subtractable = type_traits::is_subtractable_v; + + template + concept Multipliable = type_traits::is_multipliable_v; + + template + concept Dividible = type_traits::is_dividible_v; + + template + concept BinaryAndable = type_traits::is_binary_andable_v; + + template + concept BinaryOrable = type_traits::is_binary_orable_v; + + template + concept BooleanAndable = type_traits::is_boolean_andable_v; + + template + concept BooleanOrable = type_traits::is_boolean_orable_v; + +} // namespace hyperion::mpl::concepts + +#endif // HYPERION_MPL_CONCEPTS_OPERATOR_ABLE_H diff --git a/include/hyperion/mpl/concepts/std_supplemental.h b/include/hyperion/mpl/concepts/std_supplemental.h new file mode 100644 index 0000000..13359f3 --- /dev/null +++ b/include/hyperion/mpl/concepts/std_supplemental.h @@ -0,0 +1,41 @@ +/// @file std_supplemental.h +/// @author Braxton Salyer +/// @brief Supplemental C++20 concept definitions to those provided in +/// `#include ` to provide functionality missing from the standard +/// @version 0.1 +/// @date 2024-01-27 +/// +/// MIT License +/// @copyright Copyright (c) 2024 Braxton Salyer +/// +/// Permission is hereby granted, free of charge, to any person obtaining a copy +/// of this software and associated documentation files (the "Software"), to deal +/// in the Software without restriction, including without limitation the rights +/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +/// copies of the Software, and to permit persons to whom the Software is +/// furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in all +/// copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +/// SOFTWARE. + +#ifndef HYPERION_MPL_CONCEPTS_STD_SUPPLEMENTAL_H +#define HYPERION_MPL_CONCEPTS_STD_SUPPLEMENTAL_H + +#include + +namespace hyperion::mpl::concepts { + + template + concept TriviallyMovable = type_traits::is_trivially_movable_v; + +} // namespace hyperion::mpl::concepts + +#endif // HYPERION_MPL_CONCEPTS_STD_SUPPLEMENTAL_H diff --git a/include/hyperion/mpl/type_traits.h b/include/hyperion/mpl/type_traits.h index 27dd840..b6851e8 100644 --- a/include/hyperion/mpl/type_traits.h +++ b/include/hyperion/mpl/type_traits.h @@ -25,3 +25,11 @@ /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE /// SOFTWARE. +#ifndef HYPERION_MPL_TYPE_TRAITS_H +#define HYPERION_MPL_TYPE_TRAITS_H + +#include +#include +#include + +#endif // HYPERION_MPL_TYPE_TRAITS_H diff --git a/include/hyperion/mpl/type_traits/is_comparable.h b/include/hyperion/mpl/type_traits/is_comparable.h new file mode 100644 index 0000000..71044a2 --- /dev/null +++ b/include/hyperion/mpl/type_traits/is_comparable.h @@ -0,0 +1,227 @@ +/// @file is_comparable.h +/// @author Braxton Salyer +/// @brief Meta-programming type traits to determine if two types are comparable +/// in various ways +/// @version 0.1 +/// @date 2024-01-27 +/// +/// MIT License +/// @copyright Copyright (c) 2024 Braxton Salyer +/// +/// Permission is hereby granted, free of charge, to any person obtaining a copy +/// of this software and associated documentation files (the "Software"), to +/// deal in the Software without restriction, including without limitation the +/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +/// sell copies of the Software, and to permit persons to whom the Software is +/// furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +/// IN THE SOFTWARE. + +#ifndef HYPERION_MPL_TYPE_TRAITS_IS_COMPARABLE_H +#define HYPERION_MPL_TYPE_TRAITS_IS_COMPARABLE_H + +#include + +#if HYPERION_PLATFORM_STD_LIB_HAS_COMPARE + #include +#endif // HYPERION_PLATFORM_STD_LIB_HAS_COMPARE + +#include + +namespace hyperion::mpl::type_traits { + + // clang-format off + + template + struct is_equality_comparable + : std::bool_constant + {}; + + // clang-format on + + template + static inline constexpr auto is_equality_comparable_v + = is_equality_comparable::value; + // clang-format off + + template + struct is_inequality_comparable + : std::bool_constant + {}; + + // clang-format on + + template + static inline constexpr auto is_inequality_comparable_v + = is_inequality_comparable::value; + // clang-format off + + template + struct is_less_than_comparable + : std::bool_constant + {}; + + // clang-format on + + template + static inline constexpr auto is_less_than_comparable_v + = is_less_than_comparable::value; + // clang-format off + + template + struct is_less_than_or_equal_comparable + : std::bool_constant + {}; + + // clang-format on + + template + static inline constexpr auto is_less_than_or_equal_comparable_v + = is_less_than_or_equal_comparable::value; + // clang-format off + + template + struct is_greater_than_comparable + : std::bool_constant rhs; + rhs > lhs; + }> + {}; + + // clang-format on + + template + static inline constexpr auto is_greater_than_comparable_v + = is_greater_than_comparable::value; + // clang-format off + + template + struct is_greater_than_or_equal_comparable + : std::bool_constant= rhs; + rhs >= lhs; + }> + {}; + + // clang-format on + + template + static inline constexpr auto is_greater_than_or_equal_comparable_v + = is_greater_than_or_equal_comparable::value; + // clang-format off + + template + struct is_three_way_comparable : std::false_type { +#if HYPERION_PLATFORM_STD_LIB_HAS_COMPARE + using result_type = void; +#endif + }; + + template + requires std::three_way_comparable_with + struct is_three_way_comparable : std::true_type { +#if HYPERION_PLATFORM_STD_LIB_HAS_COMPARE + using result_type = std::compare_three_way_result_t; +#endif + }; + // clang-format on + + template + static inline constexpr auto is_three_way_comparable_v + = is_three_way_comparable::value; + + template + using three_way_compare_result_t = typename is_three_way_comparable::result_type; + + namespace _test { + + struct not_comparable { }; + + static_assert(is_equality_comparable_v, + "hyperion::mpl::type_traits::is_equality_comparable test case 1 failing"); + static_assert(is_equality_comparable_v, + "hyperion::mpl::type_traits::is_equality_comparable test case 2 failing"); + static_assert(!is_equality_comparable_v, + "hyperion::mpl::type_traits::is_equality_comparable test case 3 failing"); + + static_assert(is_inequality_comparable_v, + "hyperion::mpl::type_traits::is_inequality_comparable test case 1 failing"); + static_assert(is_inequality_comparable_v, + "hyperion::mpl::type_traits::is_inequality_comparable test case 2 failing"); + static_assert(!is_inequality_comparable_v, + "hyperion::mpl::type_traits::is_inequality_comparable test case 3 failing"); + + static_assert(is_less_than_comparable_v, + "hyperion::mpl::type_traits::is_less_than_comparable test case 1 failing"); + static_assert(is_less_than_comparable_v, + "hyperion::mpl::type_traits::is_less_than_comparable test case 2 failing"); + static_assert(!is_less_than_comparable_v, + "hyperion::mpl::type_traits::is_less_than_comparable test case 3 failing"); + + static_assert( + is_less_than_or_equal_comparable_v, + "hyperion::mpl::type_traits::is_less_than_or_equal_comparable test case 1 failing"); + static_assert( + is_less_than_or_equal_comparable_v, + "hyperion::mpl::type_traits::is_less_than_or_equal_comparable test case 2 failing"); + static_assert( + !is_less_than_or_equal_comparable_v, + "hyperion::mpl::type_traits::is_less_than_or_equal_comparable test case 3 failing"); + + static_assert(is_greater_than_comparable_v, + "hyperion::mpl::type_traits::is_greater_than_comparable test case 1 failing"); + static_assert(is_greater_than_comparable_v, + "hyperion::mpl::type_traits::is_greater_than_comparable test case 2 failing"); + static_assert(!is_greater_than_comparable_v, + "hyperion::mpl::type_traits::is_greater_than_comparable test case 3 failing"); + + static_assert( + is_greater_than_or_equal_comparable_v, + "hyperion::mpl::type_traits::is_greater_than_or_equal_comparable test case 1 failing"); + static_assert( + is_greater_than_or_equal_comparable_v, + "hyperion::mpl::type_traits::is_greater_than_or_equal_comparable test case 2 failing"); + static_assert( + !is_greater_than_or_equal_comparable_v, + "hyperion::mpl::type_traits::is_greater_than_or_equal_comparable test case 3 failing"); + + static_assert(is_three_way_comparable_v, + "hyperion::mpl::type_traits::is_three_way_comparable test case 1 failing"); + static_assert(is_three_way_comparable_v, + "hyperion::mpl::type_traits::is_three_way_comparable test case 2 failing"); + static_assert(!is_three_way_comparable_v, + "hyperion::mpl::type_traits::is_three_way_comparable test case 3 failing"); + +#if HYPERION_PLATFORM_STD_LIB_HAS_COMPARE + static_assert(std::same_as, std::strong_ordering>, + "hyperion::mpl::type_traits::is_three_way_comparable test case 1 failing"); + static_assert(std::same_as, std::partial_ordering>, + "hyperion::mpl::type_traits::is_three_way_comparable test case 2 failing"); + static_assert(std::same_as, void>, + "hyperion::mpl::type_traits::is_three_way_comparable test case 3 failing"); +#endif // HYPERION_PLATFORM_STD_LIB_HAS_COMPARE + } // namespace _test +} // namespace hyperion::mpl::type_traits + +#endif // HYPERION_MPL_TYPE_TRAITS_IS_COMPARABLE_H diff --git a/include/hyperion/mpl/type_traits/is_operator_able.h b/include/hyperion/mpl/type_traits/is_operator_able.h new file mode 100644 index 0000000..6822c63 --- /dev/null +++ b/include/hyperion/mpl/type_traits/is_operator_able.h @@ -0,0 +1,302 @@ +/// @file is_operator_able.h +/// @author Braxton Salyer +/// @brief Meta-programming type traits to determine if a type (or types) +/// support an operator +/// @version 0.1 +/// @date 2024-01-27 +/// +/// MIT License +/// @copyright Copyright (c) 2024 Braxton Salyer +/// +/// Permission is hereby granted, free of charge, to any person obtaining a copy +/// of this software and associated documentation files (the "Software"), to +/// deal in the Software without restriction, including without limitation the +/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +/// sell copies of the Software, and to permit persons to whom the Software is +/// furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +/// IN THE SOFTWARE. + +#ifndef HYPERION_MPL_TYPE_TRAITS_IS_OPERATOR_ABLE_H +#define HYPERION_MPL_TYPE_TRAITS_IS_OPERATOR_ABLE_H + +#include + +namespace hyperion::mpl::type_traits { + + template + struct is_unary_plusable : std::false_type { + using result_type = void; + }; + + template + requires requires(const TLhs& lhs) { +lhs; } + struct is_unary_plusable : std::true_type { + using result_type = decltype(+std::declval()); + }; + + template + static inline constexpr auto is_unary_plusable_v = is_unary_plusable::value; + + template + using unary_plus_result_t = typename is_unary_plusable::result_type; + + template + struct is_unary_minusable : std::false_type { + using result_type = void; + }; + + template + requires requires(const TLhs& lhs) { -lhs; } + struct is_unary_minusable : std::true_type { + using result_type = decltype(-std::declval()); + }; + + template + static inline constexpr auto is_unary_minusable_v = is_unary_minusable::value; + + template + using unary_minus_result_t = typename is_unary_minusable::result_type; + + template + struct is_binary_notable : std::false_type { + using result_type = void; + }; + + template + requires requires(const TLhs& lhs) { ~lhs; } + struct is_binary_notable : std::true_type { + using result_type = decltype(~std::declval()); + }; + + template + static inline constexpr auto is_binary_notable_v = is_binary_notable::value; + + template + using binary_not_result_t = typename is_binary_notable::result_type; + + template + struct is_boolean_notable : std::false_type { + using result_type = void; + }; + + template + requires requires(const TLhs& lhs) { !lhs; } + struct is_boolean_notable : std::true_type { + using result_type = decltype(!std::declval()); + }; + + template + static inline constexpr auto is_boolean_notable_v = is_boolean_notable::value; + + template + using boolean_not_result_t = typename is_boolean_notable::result_type; + + template + struct is_addressable : std::false_type { + using result_type = void; + }; + + template + requires requires(const TLhs& lhs) { &lhs; } + struct is_addressable : std::true_type { + using result_type = decltype(&std::declval()); + }; + + template + static inline constexpr auto is_addressable_v = is_addressable::value; + + template + using address_result_t = typename is_addressable::result_type; + + template + struct is_arrowable : std::false_type { + using result_type = void; + }; + + template + requires std::is_pointer_v || requires(const TLhs& lhs) { lhs.operator->(); } + struct is_arrowable : std::true_type { + using result_type = std::conditional_t, + std::remove_pointer_t, + decltype(std::declval().operator->())>; + }; + + template + static inline constexpr auto is_arrowable_v = is_arrowable::value; + + template + using arrow_result_t = typename is_arrowable::result_type; + + template + struct is_addable : std::false_type { + using result_type = void; + }; + + template + requires requires(const TLhs& lhs, const TRhs& rhs) { + lhs + rhs; + rhs + lhs; + } + struct is_addable : std::true_type { + using result_type = decltype(std::declval() + std::declval()); + }; + + template + static inline constexpr auto is_addable_v = is_addable::value; + + template + using add_result_t = typename is_addable::result_type; + + template + struct is_subtractable : std::false_type { + using result_type = void; + }; + + template + requires requires(const TLhs& lhs, const TRhs& rhs) { + lhs - rhs; + rhs - lhs; + } + struct is_subtractable : std::true_type { + using result_type = decltype(std::declval() - std::declval()); + }; + + template + static inline constexpr auto is_subtractable_v = is_subtractable::value; + + template + using subtract_result_t = typename is_subtractable::result_type; + + template + struct is_multipliable : std::false_type { + using result_type = void; + }; + + template + requires requires(const TLhs& lhs, const TRhs& rhs) { + lhs* rhs; + rhs* lhs; + } + struct is_multipliable : std::true_type { + using result_type = decltype(std::declval() * std::declval()); + }; + + template + static inline constexpr auto is_multipliable_v = is_multipliable::value; + + template + using multiply_result_t = typename is_multipliable::result_type; + + template + struct is_dividible : std::false_type { + using result_type = void; + }; + + template + requires requires(const TLhs& lhs, const TRhs& rhs) { + lhs / rhs; + rhs / lhs; + } + struct is_dividible : std::true_type { + using result_type = decltype(std::declval() / std::declval()); + }; + + template + static inline constexpr auto is_dividible_v = is_dividible::value; + + template + using divide_result_t = typename is_dividible::result_type; + + template + struct is_binary_andable : std::false_type { + using result_type = void; + }; + + template + requires requires(const TLhs& lhs, const TRhs& rhs) { + lhs & rhs; + rhs & lhs; + } + struct is_binary_andable : std::true_type { + using result_type = decltype(std::declval() & std::declval()); + }; + + template + static inline constexpr auto is_binary_andable_v = is_binary_andable::value; + + template + using binary_and_result_t = typename is_binary_andable::result_type; + + template + struct is_binary_orable : std::false_type { + using result_type = void; + }; + + template + requires requires(const TLhs& lhs, const TRhs& rhs) { + lhs | rhs; + rhs | lhs; + } + struct is_binary_orable : std::true_type { + using result_type = decltype(std::declval() | std::declval()); + }; + + template + static inline constexpr auto is_binary_orable_v = is_binary_orable::value; + + template + using binary_or_result_t = typename is_binary_orable::result_type; + + template + struct is_boolean_andable : std::false_type { + using result_type = void; + }; + + template + requires requires(const TLhs& lhs, const TRhs& rhs) { + lhs&& rhs; + rhs&& lhs; + } + struct is_boolean_andable : std::true_type { + using result_type = decltype(std::declval() && std::declval()); + }; + + template + static inline constexpr auto is_boolean_andable_v = is_boolean_andable::value; + + template + using boolean_and_result_t = typename is_boolean_andable::result_type; + + template + struct is_boolean_orable : std::false_type { + using result_type = void; + }; + + template + requires requires(const TLhs& lhs, const TRhs& rhs) { + lhs || rhs; + rhs || lhs; + } + struct is_boolean_orable : std::true_type { + using result_type = decltype(std::declval() || std::declval()); + }; + + template + static inline constexpr auto is_boolean_orable_v = is_boolean_orable::value; + + template + using boolean_or_result_t = typename is_boolean_orable::result_type; + +} // namespace hyperion::mpl::type_traits + +#endif // HYPERION_MPL_TYPE_TRAITS_IS_OPERATOR_ABLE_H diff --git a/include/hyperion/mpl/type_traits/std_supplemental.h b/include/hyperion/mpl/type_traits/std_supplemental.h new file mode 100644 index 0000000..203773f --- /dev/null +++ b/include/hyperion/mpl/type_traits/std_supplemental.h @@ -0,0 +1,45 @@ +/// @file std_supplemental.h +/// @author Braxton Salyer +/// @brief Supplemental type traits to those provided in `#include ` +/// to provide functionality missing from the standard +/// @version 0.1 +/// @date 2024-01-27 +/// +/// MIT License +/// @copyright Copyright (c) 2024 Braxton Salyer +/// +/// Permission is hereby granted, free of charge, to any person obtaining a copy +/// of this software and associated documentation files (the "Software"), to deal +/// in the Software without restriction, including without limitation the rights +/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +/// copies of the Software, and to permit persons to whom the Software is +/// furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in all +/// copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +/// SOFTWARE. + +#ifndef HYPERION_MPL_TYPE_TRAITS_STD_SUPPLEMENTAL_H +#define HYPERION_MPL_TYPE_TRAITS_STD_SUPPLEMENTAL_H + +#include + +namespace hyperion::mpl::type_traits { + + template + struct is_trivially_movable + : public std::bool_constant + && std::is_trivially_move_assignable_v> { }; + + template + static inline constexpr auto is_trivially_movable_v = is_trivially_movable::value; +} // namespace hyperion::mpl::type_traits + +#endif // HYPERION_MPL_TYPE_TRAITS_STD_SUPPLEMENTAL_H diff --git a/include/hyperion/mpl/value.h b/include/hyperion/mpl/value.h index f1fcb35..51df672 100644 --- a/include/hyperion/mpl/value.h +++ b/include/hyperion/mpl/value.h @@ -8,19 +8,380 @@ /// @copyright Copyright (c) 2024 Braxton Salyer /// /// Permission is hereby granted, free of charge, to any person obtaining a copy -/// of this software and associated documentation files (the "Software"), to deal -/// in the Software without restriction, including without limitation the rights -/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -/// copies of the Software, and to permit persons to whom the Software is +/// of this software and associated documentation files (the "Software"), to +/// deal in the Software without restriction, including without limitation the +/// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +/// sell copies of the Software, and to permit persons to whom the Software is /// furnished to do so, subject to the following conditions: /// -/// The above copyright notice and this permission notice shall be included in all -/// copies or substantial portions of the Software. +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. /// /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -/// SOFTWARE. +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +/// IN THE SOFTWARE. + +#ifndef HYPERION_MPL_VALUE_H +#define HYPERION_MPL_VALUE_H + +#include +#include +#include +#include + +#if HYPERION_PLATFORM_STD_LIB_HAS_COMPARE + #include +#endif // HYPERION_PLATFORM_STD_LIB_HAS_COMPARE + +#include +#include + +namespace hyperion::mpl { + + // clang-format off + + template + struct is_value_type + : std::bool_constant + {}; + + template + static inline constexpr auto is_value_type_v = is_value_type::value; + + template + concept ValueType = is_value_type_v; + // clang-format on + + template + struct Value { + static inline constexpr auto value = TValue; + + // NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions) + [[nodiscard]] constexpr operator decltype(value)() noexcept { + return value; + } + }; + + template + [[nodiscard]] static inline constexpr auto operator""_value() noexcept { + constexpr auto parsed = detail::parse_literal(detail::string_literal{}); + detail::check_literal_status(); + return Value{}; + } + + template + [[nodiscard]] constexpr auto + value_of([[maybe_unused]] const Value& value) noexcept -> decltype(TValue) { + return TValue; + } + + template + requires(!std::same_as>) + [[nodiscard]] constexpr auto + value_of([[maybe_unused]] const TType& value) noexcept -> decltype(TType::value) { + return TType::value; + } + + template + requires(!std::same_as>) + [[nodiscard]] constexpr auto + as_value([[maybe_unused]] const TType& value) noexcept -> Value { + return {}; + } + + template + requires concepts::UnaryPlusable + [[nodiscard]] constexpr auto + operator+([[maybe_unused]] const Value& value) noexcept -> Value { + return {}; + } + + template + requires concepts::UnaryMinusable + [[nodiscard]] constexpr auto + operator-([[maybe_unused]] const Value& value) noexcept -> Value<-TLhs> { + return {}; + } + + template + requires concepts::Addable + [[nodiscard]] constexpr auto + operator+([[maybe_unused]] const Value& lhs, + [[maybe_unused]] const Value& rhs) noexcept -> Value { + return {}; + } + + template + requires concepts::Subtractable + [[nodiscard]] constexpr auto + operator-([[maybe_unused]] const Value& lhs, + [[maybe_unused]] const Value& rhs) noexcept -> Value { + return {}; + } + + template + requires concepts::Dividible + [[nodiscard]] constexpr auto + operator/([[maybe_unused]] const Value& lhs, + [[maybe_unused]] const Value& rhs) noexcept -> Value { + return {}; + } + + template + requires concepts::Multipliable + [[nodiscard]] constexpr auto + operator*([[maybe_unused]] const Value& lhs, + [[maybe_unused]] const Value& rhs) noexcept -> Value { + return {}; + } + + template + requires concepts::BooleanAndable + [[nodiscard]] constexpr auto + operator&&([[maybe_unused]] const Value& lhs, + [[maybe_unused]] const Value& rhs) noexcept -> Value { + return {}; + } + + template + requires concepts::BooleanOrable + [[nodiscard]] constexpr auto + operator||([[maybe_unused]] const Value& lhs, + [[maybe_unused]] const Value& rhs) noexcept -> Value { + return {}; + } + + template + requires concepts::BooleanNotable + [[nodiscard]] constexpr auto + operator!([[maybe_unused]] const Value& lhs) noexcept -> Value { + return {}; + } + + template + requires concepts::BinaryAndable + [[nodiscard]] constexpr auto + operator&([[maybe_unused]] const Value& lhs, + [[maybe_unused]] const Value& rhs) noexcept -> Value { + return {}; + } + + template + requires concepts::BinaryOrable + [[nodiscard]] constexpr auto + operator|([[maybe_unused]] const Value& lhs, + [[maybe_unused]] const Value& rhs) noexcept -> Value { + return {}; + } + + template + requires concepts::BinaryNotable + [[nodiscard]] constexpr auto + operator~([[maybe_unused]] const Value& lhs) noexcept -> Value<~TLhs> { + return {}; + } + + template + requires concepts::EqualityComparable + [[nodiscard]] constexpr auto + operator==([[maybe_unused]] const Value& lhs, + [[maybe_unused]] const Value& rhs) noexcept -> Value { + return {}; + } + + template + requires concepts::InequalityComparable + [[nodiscard]] constexpr auto + operator!=([[maybe_unused]] const Value& lhs, + [[maybe_unused]] const Value& rhs) noexcept -> Value { + return {}; + } + +#if HYPERION_PLATFORM_STD_LIB_HAS_COMPARE + + template + requires concepts::ThreeWayComparable + [[nodiscard]] constexpr auto + operator<=>([[maybe_unused]] const Value& lhs, + [[maybe_unused]] const Value& rhs) noexcept -> Value TRhs> { + return {}; + } + +#else + + template + requires concepts::LessThanComparable + [[nodiscard]] constexpr auto + operator<([[maybe_unused]] const Value& lhs, + [[maybe_unused]] const Value& rhs) noexcept -> Value<(TLhs < TRhs)> { + return {}; + } + + template + requires concepts::LessThanOrEqualComparable + [[nodiscard]] constexpr auto + operator<=([[maybe_unused]] const Value& lhs, + [[maybe_unused]] const Value& rhs) noexcept -> Value<(TLhs <= TRhs)> { + return {}; + } + + template + requires concepts::GreaterThanComparable + [[nodiscard]] constexpr auto + operator>([[maybe_unused]] const Value& lhs, + [[maybe_unused]] const Value& rhs) noexcept -> Value<(TLhs > TRhs)> { + return {}; + } + + template + requires concepts::GreaterThanOrEqualComparable + [[nodiscard]] constexpr auto + operator>=([[maybe_unused]] const Value& lhs, + [[maybe_unused]] const Value& rhs) noexcept -> Value<(TLhs >= TRhs)> { + return {}; + } + +#endif // HYPERION_PLATFORM_STD_LIB_HAS_COMPARE + + namespace _test { + + static_assert(ValueType>, + "hyperion::mpl::ValueType not satisfied by hyperion::mpl::Value " + "(implementation failing)"); + static_assert(ValueType>, + "hyperion::mpl::ValueType not satisfied by std::bool_constant " + "(implementation failing)"); + + static_assert(value_of(Value<3>{}) == 3, "hyperion::mpl::value_of test case 1 (failing)"); + static_assert(value_of(std::integral_constant{}) == 3, + "hyperion::mpl::value_of test case 2 (failing)"); + static_assert(Value<3>{} == 3, + "hyperion::mpl::Value implicit conversion test case (failing)"); + + static_assert(std::same_as{})), Value<3>>, + "hyperion::mpl::as_value test case 1 (failing)"); + + static_assert(Value<3>{} == 3_value, + "hyperion::mpl::operator" + "_value test case 1 (failing)"); + + static_assert(+Value<3>{} == 3, "hyperion::mpl::operator+(Value) test case 1 (failing)"); + static_assert(-Value<3>{} == -3, "hyperion::mpl::operator-(Value) test case 1 (failing)"); + + static_assert(Value<1>{} + Value<2>{} == 3, + "hyperion::mpl::operator+(Value, Value) test case 1 (failing)"); + static_assert(Value<1>{} + Value<-2>{} == -1, + "hyperion::mpl::operator+(Value, Value) test case 2 (failing)"); + + static_assert(Value<1>{} - Value<2>{} == -1, + "hyperion::mpl::operator-(Value, Value) test case 1 (failing)"); + static_assert(Value<1>{} - Value<-2>{} == 3, + "hyperion::mpl::operator-(Value, Value) test case 2 (failing)"); + + static_assert(Value<2>{} * Value<2>{} == 4, + "hyperion::mpl::operator*(Value, Value) test case 1 (failing)"); + static_assert(Value<2>{} * Value<-2>{} == -4, + "hyperion::mpl::operator*(Value, Value) test case 2 (failing)"); + + static_assert(Value<2>{} / Value<2>{} == 1, + "hyperion::mpl::operator*(Value, Value) test case 1 (failing)"); + static_assert(Value<2>{} / Value<-2>{} == -1, + "hyperion::mpl::operator*(Value, Value) test case 2 (failing)"); + + // NOLINTNEXTLINE(readability-simplify-boolean-expr) + static_assert((Value{} && Value{}) == false, + "hyperion::mpl::operator&&(Value, Value) test case 1 (failing)"); + // NOLINTNEXTLINE(readability-simplify-boolean-expr) + static_assert((Value{} && Value{}) == true, + "hyperion::mpl::operator&&(Value, Value) test case 2 (failing)"); + + // NOLINTNEXTLINE(readability-simplify-boolean-expr) + static_assert((Value{} || Value{}) == true, + "hyperion::mpl::operator||(Value, Value) test case 1 (failing)"); + // NOLINTNEXTLINE(readability-simplify-boolean-expr) + static_assert((Value{} || Value{}) == false, + "hyperion::mpl::operator||(Value, Value) test case 2 (failing)"); + // NOLINTNEXTLINE(readability-simplify-boolean-expr) + static_assert((Value{} || Value{}) == true, + "hyperion::mpl::operator||(Value, Value) test case 3 (failing)"); + + // NOLINTNEXTLINE(readability-simplify-boolean-expr) + static_assert(!Value{} == false, + "hyperion::mpl::operator!(Value) test case 1 (failing)"); + // NOLINTNEXTLINE(readability-simplify-boolean-expr) + static_assert(!Value{} == true, + "hyperion::mpl::operator!(Value) test case 2 (failing)"); + + // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers, readability-magic-numbers) + static_assert((Value<0b1100_usize>{} & Value<0b0011_usize>{}) == 0, + "hyperion::mpl::operator&(Value, Value) test case 1 (failing)"); + // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers, readability-magic-numbers) + static_assert((Value<0b0110_usize>{} & Value<0b1100_usize>{}) == 0b0100_usize, + "hyperion::mpl::operator&(Value, Value) test case 2 (failing)"); + + // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers, readability-magic-numbers) + static_assert((Value<0b1100_usize>{} | Value<0b0011_usize>{}) == 0b1111_usize, + "hyperion::mpl::operator&(Value, Value) test case 1 (failing)"); + // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers, readability-magic-numbers) + static_assert((Value<0b0110_usize>{} | Value<0b1100_usize>{}) == 0b1110_usize, + "hyperion::mpl::operator&(Value, Value) test case 2 (failing)"); + + // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers, readability-magic-numbers) + static_assert(~Value<0b0011_usize>{} == (~0b0011_usize), + "hyperion::mpl::operator~(Value) test case 1 (failing)"); + // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers, readability-magic-numbers) + static_assert(~Value<0b1100_usize>{} == (~0b1100_usize), + "hyperion::mpl::operator~(Value) test case 2 (failing)"); + + static_assert(Value<1>{} == Value<1>{}, + "hyperion::mpl::operator==(Value, Value) test case 1 failing"); + static_assert(!(Value<1>{} == Value<2>{}), + "hyperion::mpl::operator==(Value, Value) test case 2 failing"); + + static_assert(Value<1>{} != Value<2>{}, + "hyperion::mpl::operator!=(Value, Value) test case 1 failing"); + static_assert(!(Value<1>{} != Value<1>{}), + "hyperion::mpl::operator!=(Value, Value) test case 2 failing"); + + static_assert(Value<1>{} < Value<2>{}, + "hyperion::mpl::operator<(Value, Value) test case 1 failing"); + static_assert(!(Value<1>{} < Value<1>{}), + "hyperion::mpl::operator<(Value, Value) test case 2 failing"); + + static_assert(Value<1>{} <= Value<1>{}, + "hyperion::mpl::operator<=(Value, Value) test case 1 failing"); + static_assert(Value<1>{} <= Value<2>{}, + "hyperion::mpl::operator<=(Value, Value) test case 2 failing"); + static_assert(!(Value<1>{} <= Value<0>{}), + "hyperion::mpl::operator<=(Value, Value) test case 3 failing"); + + static_assert(Value<2>{} > Value<1>{}, + "hyperion::mpl::operator>(Value, Value) test case 1 failing"); + static_assert(!(Value<1>{} > Value<1>{}), + "hyperion::mpl::operator>(Value, Value) test case 2 failing"); + + static_assert(Value<1>{} >= Value<1>{}, + "hyperion::mpl::operator>=(Value, Value) test case 1 failing"); + static_assert(Value<2>{} >= Value<1>{}, + "hyperion::mpl::operator>=(Value, Value) test case 2 failing"); + static_assert(!(Value<0>{} >= Value<1>{}), + "hyperion::mpl::operator>=(Value, Value) test case 3 failing"); + +#if HYPERION_PLATFORM_STD_LIB_HAS_COMPARE + static_assert((Value<1>{} <=> Value<1>{}) == std::strong_ordering::equal, + "hyperion::mpl::operator<=>(Value, Value) test case 1 failing"); + static_assert(Value<2>{} <=> Value<1>{} == std::strong_ordering::greater, + "hyperion::mpl::operator<=>(Value, Value) test case 2 failing"); + static_assert(Value<0>{} <=> Value<1>{} == std::strong_ordering::less, + "hyperion::mpl::operator<=>(Value, Value) test case 3 failing"); +#endif + } // namespace _test +} // namespace hyperion::mpl + +#endif // HYPERION_MPL_VALUE_H diff --git a/src/main.cpp b/src/main.cpp index 62577d1..2b53e37 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,8 +1,15 @@ +#include +#include +#include +#include +#include +#include #include -using namespace hyperion; // NOLINT(google-build-using-namespace) +using namespace hyperion; // NOLINT(google-build-using-namespace) +using namespace hyperion::mpl; // NOLINT(google-build-using-namespace) [[nodiscard]] auto main([[maybe_unused]] i32 argc, [[maybe_unused]] const char* const* argv) -> i32 { - return 0_i32; + return static_cast(0_value); } diff --git a/xmake.lua b/xmake.lua index 0647739..4b0dfdb 100644 --- a/xmake.lua +++ b/xmake.lua @@ -49,10 +49,19 @@ local hyperion_mpl_headers = { "$(projectdir)/include/hyperion/mpl/type_traits.h", "$(projectdir)/include/hyperion/mpl/value.h", } - local hyperion_mpl_algorithms_headers = { "$(projectdir)/include/hyperion/mpl/algorithms/all_of.h", } +local hyperion_mpl_concepts_headers = { + "$(projectdir)/include/hyperion/mpl/concepts/comparable.h", + "$(projectdir)/include/hyperion/mpl/concepts/operator_able.h", + "$(projectdir)/include/hyperion/mpl/concepts/std_supplemental.h", +} +local hyperion_mpl_type_traits_headers = { + "$(projectdir)/include/hyperion/mpl/type_traits/is_comparable.h", + "$(projectdir)/include/hyperion/mpl/type_traits/is_operator_able.h", + "$(projectdir)/include/hyperion/mpl/type_traits/std_supplemental.h", +} target("hyperion_mpl", function() set_kind("headeronly") @@ -60,17 +69,19 @@ target("hyperion_mpl", function() add_includedirs("$(projectdir)/include", { public = true }) add_headerfiles(hyperion_mpl_headers, { prefixdir = "hyperion/mpl", public = true }) add_headerfiles(hyperion_mpl_algorithms_headers, { prefixdir = "hyperion/mpl/algorithms", public = true }) + add_headerfiles(hyperion_mpl_concepts_headers, { prefixdir = "hyperion/mpl/concepts", public = true }) + add_headerfiles(hyperion_mpl_type_traits_headers, { prefixdir = "hyperion/mpl/type_traits", public = true }) set_default(true) on_config(function(target) - import("hyperion_compiler_settings", {alias = "settings"}) + import("hyperion_compiler_settings", { alias = "settings" }) settings.set_compiler_settings(target) end) add_options("hyperion_enable_tracy") - add_packages("doctest", {public = true}) - add_packages("hyperion_platform", {public = true}) + add_packages("doctest", { public = true }) + add_packages("hyperion_platform", { public = true }) if has_package("tracy") then - add_packages("tracy", {public = true}) + add_packages("tracy", { public = true }) end end) @@ -81,7 +92,7 @@ target("hyperion_mpl_main", function() add_deps("hyperion_mpl") set_default(true) on_config(function(target) - import("hyperion_compiler_settings", {alias = "settings"}) + import("hyperion_compiler_settings", { alias = "settings" }) settings.set_compiler_settings(target) end) end)