From a984ee355ea8bcdeeb6f5ff2dc1e17c566044223 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 7 Jun 2023 16:48:14 +0200 Subject: project: split up CMake components --- source/CMakeLists.txt | 80 +- source/examples/CMakeLists.txt | 10 + source/include/newtype/derivable.hpp | 32 - source/include/newtype/derivation_clause.hpp | 70 -- source/include/newtype/deriving.hpp | 21 - .../newtype/impl/new_type_iterator_types.hpp | 66 -- source/include/newtype/impl/new_type_storage.hpp | 139 ---- .../newtype/impl/type_traits_extensions.hpp | 853 --------------------- source/include/newtype/newtype.hpp | 550 ------------- source/include/newtype/version.hpp | 23 - source/lib/CMakeLists.txt | 21 + source/lib/include/newtype/derivable.hpp | 32 + source/lib/include/newtype/derivation_clause.hpp | 70 ++ source/lib/include/newtype/deriving.hpp | 21 + .../newtype/impl/new_type_iterator_types.hpp | 66 ++ .../lib/include/newtype/impl/new_type_storage.hpp | 139 ++++ .../newtype/impl/type_traits_extensions.hpp | 853 +++++++++++++++++++++ source/lib/include/newtype/newtype.hpp | 550 +++++++++++++ source/lib/include/newtype/version.hpp | 23 + source/test/src/arithmetic.cpp | 300 -------- source/test/src/conversion_suite.cpp | 201 ----- source/test/src/derivation_clause_suite.cpp | 312 -------- source/test/src/equality_comparison_suite.cpp | 188 ----- source/test/src/hash_suite.cpp | 69 -- source/test/src/io_operators_suite.cpp | 121 --- source/test/src/iterable_suite.cpp | 719 ----------------- source/test/src/new_type_constructor_suite.cpp | 91 --- source/test/src/relational_operators_suite.cpp | 321 -------- source/tests/CMakeLists.txt | 34 + source/tests/src/arithmetic.cpp | 300 ++++++++ source/tests/src/conversion_suite.cpp | 201 +++++ source/tests/src/derivation_clause_suite.cpp | 312 ++++++++ source/tests/src/equality_comparison_suite.cpp | 188 +++++ source/tests/src/hash_suite.cpp | 69 ++ source/tests/src/io_operators_suite.cpp | 121 +++ source/tests/src/iterable_suite.cpp | 719 +++++++++++++++++ source/tests/src/new_type_constructor_suite.cpp | 91 +++ source/tests/src/relational_operators_suite.cpp | 321 ++++++++ 38 files changed, 4145 insertions(+), 4152 deletions(-) create mode 100644 source/examples/CMakeLists.txt delete mode 100644 source/include/newtype/derivable.hpp delete mode 100644 source/include/newtype/derivation_clause.hpp delete mode 100644 source/include/newtype/deriving.hpp delete mode 100644 source/include/newtype/impl/new_type_iterator_types.hpp delete mode 100644 source/include/newtype/impl/new_type_storage.hpp delete mode 100644 source/include/newtype/impl/type_traits_extensions.hpp delete mode 100644 source/include/newtype/newtype.hpp delete mode 100644 source/include/newtype/version.hpp create mode 100644 source/lib/CMakeLists.txt create mode 100644 source/lib/include/newtype/derivable.hpp create mode 100644 source/lib/include/newtype/derivation_clause.hpp create mode 100644 source/lib/include/newtype/deriving.hpp create mode 100644 source/lib/include/newtype/impl/new_type_iterator_types.hpp create mode 100644 source/lib/include/newtype/impl/new_type_storage.hpp create mode 100644 source/lib/include/newtype/impl/type_traits_extensions.hpp create mode 100644 source/lib/include/newtype/newtype.hpp create mode 100644 source/lib/include/newtype/version.hpp delete mode 100644 source/test/src/arithmetic.cpp delete mode 100644 source/test/src/conversion_suite.cpp delete mode 100644 source/test/src/derivation_clause_suite.cpp delete mode 100644 source/test/src/equality_comparison_suite.cpp delete mode 100644 source/test/src/hash_suite.cpp delete mode 100644 source/test/src/io_operators_suite.cpp delete mode 100644 source/test/src/iterable_suite.cpp delete mode 100644 source/test/src/new_type_constructor_suite.cpp delete mode 100644 source/test/src/relational_operators_suite.cpp create mode 100644 source/tests/CMakeLists.txt create mode 100644 source/tests/src/arithmetic.cpp create mode 100644 source/tests/src/conversion_suite.cpp create mode 100644 source/tests/src/derivation_clause_suite.cpp create mode 100644 source/tests/src/equality_comparison_suite.cpp create mode 100644 source/tests/src/hash_suite.cpp create mode 100644 source/tests/src/io_operators_suite.cpp create mode 100644 source/tests/src/iterable_suite.cpp create mode 100644 source/tests/src/new_type_constructor_suite.cpp create mode 100644 source/tests/src/relational_operators_suite.cpp diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 0bd0876..c84eda9 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -5,84 +5,12 @@ project("newtype" DESCRIPTION "A library of types and functions to create strong type aliases" ) -enable_testing() - -# Project dependencies - -find_package("Catch2" "3.1" - COMPONENTS "Catch2WithMain" - REQUIRED -) - -include("Catch") - # Project Options option(BUILD_EXAMPLES "Build the library examples" OFF) -# 'newtype' library - -add_library("${PROJECT_NAME}" INTERFACE) - -target_include_directories("${PROJECT_NAME}" INTERFACE - $ - $ -) - -target_compile_features("${PROJECT_NAME}" INTERFACE - "cxx_std_20" -) - -install(TARGETS "${PROJECT_NAME}" - EXPORT "${PROJECT_NAME}Targets" - PUBLIC_HEADER DESTINATION "include" -) - -install(DIRECTORY "${PROJECT_SOURCE_DIR}/include/" - DESTINATION "include" -) - -add_library("${PROJECT_NAME}::${PROJECT_NAME}" ALIAS "${PROJECT_NAME}") - -# 'newtype' tests - -add_executable("${PROJECT_NAME}_tests" - "test/src/arithmetic.cpp" - # "test/src/conversion_suite.cpp" - # "test/src/derivation_clause_suite.cpp" - # "test/src/equality_comparison_suite.cpp" - # "test/src/hash_suite.cpp" - # "test/src/io_operators_suite.cpp" - # "test/src/iterable_suite.cpp" - # "test/src/new_type_constructor_suite.cpp" - # "test/src/relational_operators_suite.cpp" -) - -target_link_libraries("${PROJECT_NAME}_tests" - "${PROJECT_NAME}::${PROJECT_NAME}" - "Catch2::Catch2WithMain" -) - -target_compile_options("${PROJECT_NAME}_tests" PRIVATE - "$<$:-Wall>" - "$<$:-Wextra>" - "$<$:-Werror>" - "$<$:-pedantic-errors>" -) - -catch_discover_tests("${PROJECT_NAME}_tests") - -# 'newtype' examples - -if(BUILD_EXAMPLES) - function(add_example NAME) - add_executable("ex_${NAME}" - "examples/src/${NAME}.cpp" - ) - target_link_libraries("ex_${NAME}" "${PROJECT_NAME}") - endfunction() +# Project Components - add_example("basic_usage") - add_example("basic_usage_with_show") - add_example("basic_usage_with_read") -endif() +add_subdirectory("lib") +add_subdirectory("tests") +add_subdirectory("examples") diff --git a/source/examples/CMakeLists.txt b/source/examples/CMakeLists.txt new file mode 100644 index 0000000..5b6ddd8 --- /dev/null +++ b/source/examples/CMakeLists.txt @@ -0,0 +1,10 @@ +if(BUILD_EXAMPLES) + function(add_example NAME) + add_executable("ex_${NAME}" "src/${NAME}.cpp") + target_link_libraries("ex_${NAME}" "${PROJECT_NAME}") + endfunction() + + add_example("basic_usage") + add_example("basic_usage_with_show") + add_example("basic_usage_with_read") +endif() diff --git a/source/include/newtype/derivable.hpp b/source/include/newtype/derivable.hpp deleted file mode 100644 index c798c59..0000000 --- a/source/include/newtype/derivable.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef NEWTYPE_DERIVABLE_HPP -#define NEWTYPE_DERIVABLE_HPP - -#include "newtype/version.hpp" - -namespace nt -{ - - template - struct derivable final - { - using tag_type = DerivableTag; - }; - - inline namespace derivables - { - - auto constexpr Arithmetic = derivable{}; - auto constexpr EqBase = derivable{}; - auto constexpr Hash = derivable{}; - auto constexpr ImplicitConversion = derivable{}; - auto constexpr Indirection = derivable{}; - auto constexpr Iterable = derivable{}; - auto constexpr Read = derivable{}; - auto constexpr Relational = derivable{}; - auto constexpr Show = derivable{}; - - } // namespace derivables - -} // namespace nt - -#endif \ No newline at end of file diff --git a/source/include/newtype/derivation_clause.hpp b/source/include/newtype/derivation_clause.hpp deleted file mode 100644 index 6de70e1..0000000 --- a/source/include/newtype/derivation_clause.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef NEWTYPE_DERIVATION_CLAUSE_HPP -#define NEWTYPE_DERIVATION_CLAUSE_HPP - -#include "newtype/derivable.hpp" -#include "newtype/version.hpp" - -#include - -namespace nt -{ - - template - struct derivation_clause - { - constexpr derivation_clause(derivable...) noexcept - { - } - - template - auto constexpr operator()(derivable) const noexcept -> bool - { - return (std::is_same_v || ...); - } - - template - auto constexpr operator()(derivable, derivable...) const noexcept -> bool - { - return (*this)(derivable{}) && (*this)(derivable{}...); - } - - template - auto constexpr operator<(derivation_clause other) const noexcept -> bool - { - return (sizeof...(DerivableTags) < sizeof...(OtherDerivableTags)) && other(derivable{}...); - } - - template - auto constexpr operator>(derivation_clause other) const noexcept -> bool - { - return other < *this; - } - - template - auto constexpr operator==(derivation_clause other) const noexcept -> bool - { - return sizeof...(DerivableTags) == sizeof...(OtherDerivableTags) && other(derivable{}...); - } - - template - auto constexpr operator!=(derivation_clause other) const noexcept -> bool - { - return !(*this == other); - } - - template - auto constexpr operator<=(derivation_clause other) const noexcept -> bool - { - return *this < other || *this == other; - } - - template - auto constexpr operator>=(derivation_clause other) const noexcept -> bool - { - return *this > other || *this == other; - } - }; - -} // namespace nt - -#endif \ No newline at end of file diff --git a/source/include/newtype/deriving.hpp b/source/include/newtype/deriving.hpp deleted file mode 100644 index ae10bab..0000000 --- a/source/include/newtype/deriving.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef NEWTYPE_DERIVING_HPP -#define NEWTYPE_DERIVING_HPP - -#include "newtype/derivable.hpp" -#include "newtype/derivation_clause.hpp" -#include "newtype/version.hpp" - -#include - -namespace nt -{ - - template - auto constexpr deriving(derivable... features) noexcept -> derivation_clause - { - return {features...}; - } - -} // namespace nt - -#endif \ No newline at end of file diff --git a/source/include/newtype/impl/new_type_iterator_types.hpp b/source/include/newtype/impl/new_type_iterator_types.hpp deleted file mode 100644 index 2ea8274..0000000 --- a/source/include/newtype/impl/new_type_iterator_types.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef NEWTYPE_IMPL_NEW_TYPE_ITERATOR_TYPES_HPP -#define NEWTYPE_IMPL_NEW_TYPE_ITERATOR_TYPES_HPP - -#include "newtype/version.hpp" - -#include - -namespace nt::impl -{ - - template> - struct new_type_iterator - { - }; - - template - struct new_type_iterator> - { - using iterator = typename T::iterator; - }; - - template> - struct new_type_const_iterator - { - }; - - template - struct new_type_const_iterator> - { - using const_iterator = typename T::const_iterator; - }; - - template> - struct new_type_reverse_iterator - { - }; - - template - struct new_type_reverse_iterator> - { - using reverse_iterator = typename T::reverse_iterator; - }; - - template> - struct new_type_const_reverse_iterator - { - }; - - template - struct new_type_const_reverse_iterator> - { - using const_reverse_iterator = typename T::const_reverse_iterator; - }; - - template - struct new_type_iterator_types - : new_type_iterator - , new_type_const_iterator - , new_type_reverse_iterator - , new_type_const_reverse_iterator - { - }; - -} // namespace nt::impl - -#endif \ No newline at end of file diff --git a/source/include/newtype/impl/new_type_storage.hpp b/source/include/newtype/impl/new_type_storage.hpp deleted file mode 100644 index f7842af..0000000 --- a/source/include/newtype/impl/new_type_storage.hpp +++ /dev/null @@ -1,139 +0,0 @@ -#ifndef NEWTYPE_IMPL_NEW_TYPE_STORAGE_HPP -#define NEWTYPE_IMPL_NEW_TYPE_STORAGE_HPP - -#include "newtype/version.hpp" - -#include -#include - -namespace nt::impl -{ - - template - struct new_type_storage - { - constexpr new_type_storage() noexcept(std::is_nothrow_default_constructible_v) - : m_value{} - { - } - - constexpr new_type_storage(BaseType const & value) - : m_value{value} - { - } - - constexpr new_type_storage(BaseType && value) - : m_value{std::move(value)} - { - } - - BaseType m_value; - }; - - template> - struct new_type_constructor : new_type_storage - { - using new_type_storage::new_type_storage; - }; - - template - struct new_type_constructor : new_type_storage - { - using new_type_storage::new_type_storage; - - constexpr new_type_constructor() = delete; - }; - - template> - struct new_type_copy_constructor : new_type_constructor - { - using new_type_constructor::new_type_constructor; - - constexpr new_type_copy_constructor(new_type_copy_constructor const &) = default; - constexpr new_type_copy_constructor(new_type_copy_constructor &&) = default; - auto constexpr operator=(new_type_copy_constructor &) -> new_type_copy_constructor & = default; - auto constexpr operator=(new_type_copy_constructor &&) -> new_type_copy_constructor & = default; - }; - - template - struct new_type_copy_constructor : new_type_constructor - { - using new_type_constructor::new_type_constructor; - - constexpr new_type_copy_constructor(new_type_copy_constructor const &) = delete; - constexpr new_type_copy_constructor(new_type_copy_constructor &&) = default; - constexpr new_type_copy_constructor(BaseType const &) = delete; - auto constexpr operator=(new_type_copy_constructor &) -> new_type_copy_constructor & = default; - auto constexpr operator=(new_type_copy_constructor &&) -> new_type_copy_constructor & = default; - }; - - template> - struct new_type_move_constructor : new_type_copy_constructor - { - using new_type_copy_constructor::new_type_copy_constructor; - - constexpr new_type_move_constructor(new_type_move_constructor const &) = default; - constexpr new_type_move_constructor(new_type_move_constructor &&) = default; - auto constexpr operator=(new_type_move_constructor &) -> new_type_move_constructor & = default; - auto constexpr operator=(new_type_move_constructor &&) -> new_type_move_constructor & = default; - }; - - template - struct new_type_move_constructor : new_type_copy_constructor - { - using new_type_copy_constructor::new_type_copy_constructor; - - constexpr new_type_move_constructor(new_type_move_constructor const &) = default; - constexpr new_type_move_constructor(new_type_move_constructor &&) = delete; - constexpr new_type_move_constructor(BaseType &&) = delete; - auto constexpr operator=(new_type_move_constructor &) -> new_type_move_constructor & = default; - auto constexpr operator=(new_type_move_constructor &&) -> new_type_move_constructor & = default; - }; - - template> - struct new_type_copy_assignment : new_type_move_constructor - { - using new_type_move_constructor::new_type_move_constructor; - - constexpr new_type_copy_assignment(new_type_copy_assignment const &) = default; - constexpr new_type_copy_assignment(new_type_copy_assignment &&) = default; - auto constexpr operator=(new_type_copy_assignment &) -> new_type_copy_assignment & = default; - auto constexpr operator=(new_type_copy_assignment &&) -> new_type_copy_assignment & = default; - }; - - template - struct new_type_copy_assignment : new_type_move_constructor - { - using new_type_move_constructor::new_type_move_constructor; - - constexpr new_type_copy_assignment(new_type_copy_assignment const &) = default; - constexpr new_type_copy_assignment(new_type_copy_assignment &&) = default; - auto constexpr operator=(new_type_copy_assignment &) -> new_type_copy_assignment & = default; - auto constexpr operator=(new_type_copy_assignment &&) -> new_type_copy_assignment & = delete; - }; - - template> - struct new_type_move_assignment : new_type_copy_assignment - { - using new_type_copy_assignment::new_type_copy_assignment; - - constexpr new_type_move_assignment(new_type_move_assignment const &) = default; - constexpr new_type_move_assignment(new_type_move_assignment &&) = default; - auto constexpr operator=(new_type_move_assignment &) -> new_type_move_assignment & = default; - auto constexpr operator=(new_type_move_assignment &&) -> new_type_move_assignment & = default; - }; - - template - struct new_type_move_assignment : new_type_copy_assignment - { - using new_type_copy_assignment::new_type_copy_assignment; - - constexpr new_type_move_assignment(new_type_move_assignment const &) = default; - constexpr new_type_move_assignment(new_type_move_assignment &&) = default; - auto constexpr operator=(new_type_move_assignment &) -> new_type_move_assignment & = default; - auto constexpr operator=(new_type_move_assignment &&) -> new_type_move_assignment & = delete; - }; - -} // namespace nt::impl - -#endif diff --git a/source/include/newtype/impl/type_traits_extensions.hpp b/source/include/newtype/impl/type_traits_extensions.hpp deleted file mode 100644 index dc41649..0000000 --- a/source/include/newtype/impl/type_traits_extensions.hpp +++ /dev/null @@ -1,853 +0,0 @@ -#ifndef NEWTYPE_IMPL_TYPE_TRAITS_EXTENSIONS_HPP -#define NEWTYPE_IMPL_TYPE_TRAITS_EXTENSIONS_HPP - -#include "newtype/version.hpp" - -#include -#include -#include -#include - -namespace nt::impl -{ - - inline namespace equality_comparable - { - - template - struct is_equality_comparable : std::false_type - { - }; - - template - struct is_equality_comparable() == std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_equality_comparable_v = is_equality_comparable::value; - - template - struct is_nothrow_equality_comparable : std::false_type - { - }; - - template - struct is_nothrow_equality_comparable() == std::declval())>> - : std::bool_constant() == std::declval())> - { - }; - - template - auto constexpr is_nothrow_equality_comparable_v = is_nothrow_equality_comparable::value; - - template - struct is_inequality_comparable : std::false_type - { - }; - - template - struct is_inequality_comparable() != std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_inequality_comparable_v = is_inequality_comparable::value; - - template - struct is_nothrow_inequality_comparable : std::false_type - { - }; - - template - struct is_nothrow_inequality_comparable() != std::declval())>> - : std::bool_constant() != std::declval())> - { - }; - - template - auto constexpr is_nothrow_inequality_comparable_v = is_nothrow_inequality_comparable::value; - - } // namespace equality_comparable - - inline namespace relationally_comparable - { - - template - struct is_less_than_comparable : std::false_type - { - }; - - template - struct is_less_than_comparable() < std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_less_than_comparable_v = is_less_than_comparable::value; - - template - struct is_nothrow_less_than_comparable : std::false_type - { - }; - - template - struct is_nothrow_less_than_comparable() < std::declval())>> - : std::bool_constant() < std::declval())> - { - }; - - template - auto constexpr is_nothrow_less_than_comparable_v = is_nothrow_less_than_comparable::value; - - template - struct is_greater_than_comparable : std::false_type - { - }; - - template - struct is_greater_than_comparable() > std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_greater_than_comparable_v = is_greater_than_comparable::value; - - template - struct is_nothrow_greater_than_comparable : std::false_type - { - }; - - template - struct is_nothrow_greater_than_comparable() > std::declval())>> - : std::bool_constant() > std::declval())> - { - }; - - template - auto constexpr is_nothrow_greater_than_comparable_v = is_nothrow_greater_than_comparable::value; - - template - struct is_less_than_equal_to_comparable : std::false_type - { - }; - - template - struct is_less_than_equal_to_comparable() <= std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_less_than_equal_to_comparable_v = is_less_than_equal_to_comparable::value; - - template - struct is_nothrow_less_than_equal_to_comparable : std::false_type - { - }; - - template - struct is_nothrow_less_than_equal_to_comparable() <= std::declval())>> - : std::bool_constant() <= std::declval())> - { - }; - - template - auto constexpr is_nothrow_less_than_equal_to_comparable_v = is_nothrow_less_than_equal_to_comparable::value; - - template - struct is_greater_than_equal_to_comparable : std::false_type - { - }; - - template - struct is_greater_than_equal_to_comparable() >= std::declval())>> - : std::true_type - { - }; - - template - auto constexpr is_greater_than_equal_to_comparable_v = is_greater_than_equal_to_comparable::value; - - template - struct is_nothrow_greater_than_equal_to_comparable : std::false_type - { - }; - - template - struct is_nothrow_greater_than_equal_to_comparable() >= std::declval())>> - : std::bool_constant() >= std::declval())> - { - }; - - template - auto constexpr is_nothrow_greater_than_equal_to_comparable_v = is_nothrow_greater_than_equal_to_comparable::value; - } // namespace relationally_comparable - - inline namespace iostreamable - { - - template - struct is_output_streamable : std::false_type - { - }; - - template - struct is_output_streamable() << std::declval())>> - : std::true_type - { - }; - - template - auto constexpr is_output_streamable_v = is_output_streamable::value; - - template - struct is_nothrow_output_streamable : std::false_type - { - }; - - template - struct is_nothrow_output_streamable() << std::declval())>> - : std::bool_constant() << std::declval())> - { - }; - - template - auto constexpr is_nothrow_output_streamable_v = is_nothrow_output_streamable::value; - - template - struct is_input_streamable : std::false_type - { - }; - - template - struct is_input_streamable() >> std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_input_streamable_v = is_input_streamable::value; - - template - struct is_nothrow_input_streamable : std::false_type - { - }; - - template - struct is_nothrow_input_streamable() >> std::declval())>> - : std::bool_constant() >> std::declval())> - { - }; - - template - auto constexpr is_nothrow_input_streamable_v = is_nothrow_input_streamable::value; - - } // namespace iostreamable - - inline namespace arithmetic - { - - template - struct is_addable : std::false_type - { - }; - - template - struct is_addable() + std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_addable_v = is_addable::value; - - template - struct is_nothrow_addable : std::false_type - { - }; - - template - struct is_nothrow_addable() + std::declval())>> - : std::bool_constant() + std::declval())> - { - }; - - template - auto constexpr is_nothrow_addable_v = is_nothrow_addable::value; - - template - struct is_subtractable : std::false_type - { - }; - - template - struct is_subtractable() - std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_subtractable_v = is_subtractable::value; - - template - struct is_nothrow_subtractable : std::false_type - { - }; - - template - struct is_nothrow_subtractable() - std::declval())>> - : std::bool_constant() - std::declval())> - { - }; - - template - auto constexpr is_nothrow_subtractable_v = is_nothrow_subtractable::value; - - template - struct is_multipliable : std::false_type - { - }; - - template - struct is_multipliable() * std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_multipliable_v = is_multipliable::value; - - template - struct is_nothrow_multipliable : std::false_type - { - }; - - template - struct is_nothrow_multipliable() * std::declval())>> - : std::bool_constant() * std::declval())> - { - }; - - template - auto constexpr is_nothrow_multipliable_v = is_nothrow_multipliable::value; - - template - struct is_dividable : std::false_type - { - }; - - template - struct is_dividable() / std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_dividable_v = is_dividable::value; - - template - struct is_nothrow_dividable : std::false_type - { - }; - - template - struct is_nothrow_dividable() / std::declval())>> - : std::bool_constant() / std::declval())> - { - }; - - template - auto constexpr is_nothrow_dividable_v = is_nothrow_dividable::value; - - } // namespace arithmetic - - inline namespace compound_arithmetic - { - - template - struct is_add_assignable : std::false_type - { - }; - - template - struct is_add_assignable() += std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_add_assignable_v = is_add_assignable::value; - - template - struct is_nothrow_add_assignable : std::false_type - { - }; - - template - struct is_nothrow_add_assignable() += std::declval())>> - : std::bool_constant() += std::declval())> - { - }; - - template - auto constexpr is_nothrow_add_assignable_v = is_nothrow_add_assignable::value; - - template - struct is_subtract_assignable : std::false_type - { - }; - - template - struct is_subtract_assignable() -= std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_subtract_assignable_v = is_subtract_assignable::value; - - template - struct is_nothrow_subtract_assignable : std::false_type - { - }; - - template - struct is_nothrow_subtract_assignable() -= std::declval())>> - : std::bool_constant() -= std::declval())> - { - }; - - template - auto constexpr is_nothrow_subtract_assignable_v = is_nothrow_subtract_assignable::value; - - template - struct is_multiply_assignable : std::false_type - { - }; - - template - struct is_multiply_assignable() *= std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_multiply_assignable_v = is_multiply_assignable::value; - - template - struct is_nothrow_multiply_assignable : std::false_type - { - }; - - template - struct is_nothrow_multiply_assignable() *= std::declval())>> - : std::bool_constant() *= std::declval())> - { - }; - - template - auto constexpr is_nothrow_multiply_assignable_v = is_nothrow_multiply_assignable::value; - - template - struct is_divide_assignable : std::false_type - { - }; - - template - struct is_divide_assignable() /= std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_divide_assignable_v = is_divide_assignable::value; - - template - struct is_nothrow_divide_assignable : std::false_type - { - }; - - template - struct is_nothrow_divide_assignable() /= std::declval())>> - : std::bool_constant() /= std::declval())> - { - }; - - template - auto constexpr is_nothrow_divide_assignable_v = is_nothrow_divide_assignable::value; - - } // namespace compound_arithmetic - - inline namespace std_support - { - - template - struct is_hashable : std::false_type - { - }; - - template - struct is_hashable const &>()(std::declval()))>> - : std::is_same const &>()(std::declval()))> - { - }; - - template - auto constexpr is_hashable_v = is_hashable::value; - - } // namespace std_support - - inline namespace iterable_begin - { - template - struct has_free_begin : std::false_type - { - }; - - template - struct has_free_begin()))>> - : std::is_same()))>> - { - }; - - template - struct has_free_begin()))>> - : std::is_same()))>> - { - }; - - template - auto constexpr has_free_begin_v = has_free_begin::value; - - template - struct has_member_begin : std::false_type - { - }; - - template - struct has_member_begin().begin())>> - : std::is_same().begin())>> - { - }; - - template - struct has_member_begin().begin())>> - : std::is_same().begin())>> - { - }; - - template - auto constexpr has_member_begin_v = has_member_begin::value; - - template - struct has_begin : std::disjunction, has_member_begin> - { - }; - - template - auto constexpr has_begin_v = has_begin::value; - } // namespace iterable_begin - - inline namespace iterable_cbegin - { - template - struct has_free_cbegin : std::false_type - { - }; - - template - struct has_free_cbegin()))>> - : std::is_same()))>> - { - }; - - template - auto constexpr has_free_cbegin_v = has_free_cbegin::value; - - template - struct has_member_cbegin : std::false_type - { - }; - - template - struct has_member_cbegin().cbegin())>> - : std::is_same().cbegin())> - { - }; - - template - auto constexpr has_member_cbegin_v = has_member_cbegin::value; - - template - struct has_cbegin : std::disjunction, has_member_cbegin> - { - }; - - template - auto constexpr has_cbegin_v = has_cbegin::value; - } // namespace iterable_cbegin - - inline namespace iterable_rbegin - { - template - struct has_free_rbegin : std::false_type - { - }; - - template - struct has_free_rbegin()))>> - : std::is_same()))>> - { - }; - - template - struct has_free_rbegin()))>> - : std::is_same()))>> - { - }; - - template - auto constexpr has_free_rbegin_v = has_free_rbegin::value; - - template - struct has_member_rbegin : std::false_type - { - }; - - template - struct has_member_rbegin().rbegin())>> - : std::is_same().rbegin())>> - { - }; - - template - struct has_member_rbegin().rbegin())>> - : std::is_same().rbegin())>> - { - }; - - template - auto constexpr has_member_rbegin_v = has_member_rbegin::value; - - template - struct has_rbegin : std::disjunction, has_member_rbegin> - { - }; - - template - auto constexpr has_rbegin_v = has_rbegin::value; - } // namespace iterable_rbegin - - inline namespace iterable_crbegin - { - template - struct has_free_crbegin : std::false_type - { - }; - - template - struct has_free_crbegin()))>> - : std::is_same()))>> - { - }; - - template - auto constexpr has_free_crbegin_v = has_free_crbegin::value; - - template - struct has_member_crbegin : std::false_type - { - }; - - template - struct has_member_crbegin().crbegin())>> - : std::is_same().crbegin())>> - { - }; - - template - auto constexpr has_member_crbegin_v = has_member_crbegin::value; - - template - struct has_crbegin : std::disjunction, has_member_crbegin> - { - }; - - template - auto constexpr has_crbegin_v = has_crbegin::value; - } // namespace iterable_crbegin - - inline namespace iterable_end - { - template - struct has_free_end : std::false_type - { - }; - - template - struct has_free_end()))>> - : std::is_same()))>> - { - }; - - template - struct has_free_end()))>> - : std::is_same()))>> - { - }; - - template - auto constexpr has_free_end_v = has_free_end::value; - - template - struct has_member_end : std::false_type - { - }; - - template - struct has_member_end().end())>> - : std::is_same().end())>> - { - }; - - template - struct has_member_end().end())>> - : std::is_same().end())>> - { - }; - - template - auto constexpr has_member_end_v = has_member_end::value; - - template - struct has_end : std::disjunction, has_member_end> - { - }; - - template - auto constexpr has_end_v = has_end::value; - } // namespace iterable_end - - inline namespace iterable_cend - { - template - struct has_free_cend : std::false_type - { - }; - - template - struct has_free_cend()))>> - : std::is_same()))>> - { - }; - - template - auto constexpr has_free_cend_v = has_free_cend::value; - - template - struct has_member_cend : std::false_type - { - }; - - template - struct has_member_cend().cend())>> - : std::is_same().cend())> - { - }; - - template - auto constexpr has_member_cend_v = has_member_cend::value; - - template - struct has_cend : std::disjunction, has_member_cend> - { - }; - - template - auto constexpr has_cend_v = has_cend::value; - } // namespace iterable_cend - - inline namespace iterable_rend - { - template - struct has_free_rend : std::false_type - { - }; - - template - struct has_free_rend()))>> - : std::is_same()))>> - { - }; - - template - struct has_free_rend()))>> - : std::is_same()))>> - { - }; - - template - auto constexpr has_free_rend_v = has_free_rend::value; - - template - struct has_member_rend : std::false_type - { - }; - - template - struct has_member_rend().rend())>> - : std::is_same().rend())>> - { - }; - - template - struct has_member_rend().rend())>> - : std::is_same().rend())>> - { - }; - - template - auto constexpr has_member_rend_v = has_member_rend::value; - - template - struct has_rend : std::disjunction, has_member_rend> - { - }; - - template - auto constexpr has_rend_v = has_rend::value; - } // namespace iterable_rend - - inline namespace iterable_crend - { - template - struct has_free_crend : std::false_type - { - }; - - template - struct has_free_crend()))>> - : std::is_same()))>> - { - }; - - template - auto constexpr has_free_crend_v = has_free_crend::value; - - template - struct has_member_crend : std::false_type - { - }; - - template - struct has_member_crend().crend())>> - : std::is_same().crend())>> - { - }; - - template - auto constexpr has_member_crend_v = has_member_crend::value; - - template - struct has_crend : std::disjunction, has_member_crend> - { - }; - - template - auto constexpr has_crend_v = has_crend::value; - } // namespace iterable_crend - -} // namespace nt::impl - -#endif \ No newline at end of file diff --git a/source/include/newtype/newtype.hpp b/source/include/newtype/newtype.hpp deleted file mode 100644 index e2704f3..0000000 --- a/source/include/newtype/newtype.hpp +++ /dev/null @@ -1,550 +0,0 @@ -#ifndef NEWTYPE_NEWTYPE_HPP -#define NEWTYPE_NEWTYPE_HPP - -#include "newtype/derivable.hpp" -#include "newtype/deriving.hpp" -#include "newtype/impl/new_type_iterator_types.hpp" -#include "newtype/impl/new_type_storage.hpp" -#include "newtype/impl/type_traits_extensions.hpp" -#include "newtype/version.hpp" - -#include -#include -#include -#include - -namespace nt -{ - - template - class new_type - : impl::new_type_move_assignment - , public impl::new_type_iterator_types - { - static_assert(!std::is_reference_v, "The base type must not be a reference type"); - static_assert(!std::is_void_v>, "The base type must not be possibly cv-qualified void"); - - template - auto friend operator>>(std::basic_istream &, new_type &) noexcept( - impl::is_nothrow_input_streamable_v, BaseTypeT>) - -> std::enable_if_t, BaseTypeT>, - std::basic_istream> &; - - template - auto constexpr friend - operator+=(new_type & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_add_assignable_v) - -> std::enable_if_t, - new_type &>; - - template - auto constexpr friend - operator-=(new_type & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_subtract_assignable_v) - -> std::enable_if_t, - new_type &>; - - template - auto constexpr friend - operator*=(new_type & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_multiply_assignable_v) - -> std::enable_if_t, - new_type &>; - - template - auto constexpr friend - operator/=(new_type & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_divide_assignable_v) - -> std::enable_if_t, - new_type &>; - - template - auto constexpr friend begin(new_type & obj) - -> std::enable_if_t, - typename new_type::iterator>; - - template - auto constexpr friend begin(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_iterator>; - - template - auto constexpr friend cbegin(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_iterator>; - - template - auto constexpr friend rbegin(new_type & obj) - -> std::enable_if_t, - typename new_type::reverse_iterator>; - - template - auto constexpr friend rbegin(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_reverse_iterator>; - - template - auto constexpr friend crbegin(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_reverse_iterator>; - - template - auto constexpr friend end(new_type & obj) - -> std::enable_if_t, - typename new_type::iterator>; - - template - auto constexpr friend end(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_iterator>; - - template - auto constexpr friend cend(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_iterator>; - - template - auto constexpr friend rend(new_type & obj) - -> std::enable_if_t, - typename new_type::reverse_iterator>; - - template - auto constexpr friend rend(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_reverse_iterator>; - - template - auto constexpr friend crend(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_reverse_iterator>; - - using super = impl::new_type_move_assignment; - - public: - using base_type = BaseType; - using tag_type = TagType; - using derivation_clause_type = decltype(DerivationClause); - - auto constexpr static derivation_clause = DerivationClause; - - using super::super; - - constexpr new_type() noexcept(std::is_nothrow_default_constructible_v) = default; - constexpr new_type(new_type const &) noexcept(std::is_nothrow_copy_constructible_v) = default; - constexpr new_type(new_type &&) noexcept(std::is_nothrow_move_constructible_v) = default; - - auto constexpr operator=(new_type const &) noexcept(std::is_nothrow_copy_assignable_v) -> new_type & = default; - auto constexpr operator=(new_type &&) noexcept(std::is_nothrow_move_assignable_v) -> new_type & = default; - - auto constexpr decay() const noexcept(std::is_nothrow_copy_constructible_v) -> BaseType - { - return this->m_value; - } - - template * = nullptr> - constexpr operator base_type() const noexcept(std::is_nothrow_copy_constructible_v) - { - return decay(); - } - - template * = nullptr> - explicit constexpr operator base_type() const noexcept(std::is_nothrow_copy_constructible_v) - { - return decay(); - } - - template - auto constexpr operator->() noexcept -> std::enable_if_t - { - return std::addressof(this->m_value); - } - - template - auto constexpr operator->() const noexcept -> std::enable_if_t - { - return std::addressof(this->m_value); - } - - template * = nullptr> - auto constexpr begin() - -> std::enable_if_t, typename NewType::iterator> - { - return this->m_value.begin(); - } - - template - auto constexpr begin() const -> std::enable_if_t, - typename NewType::const_iterator> - { - return this->m_value.begin(); - } - - template - auto constexpr cbegin() const -> std::enable_if_t, - typename NewType::const_iterator> - { - return this->m_value.cbegin(); - } - - template * = nullptr> - auto constexpr rbegin() - -> std::enable_if_t, typename NewType::reverse_iterator> - { - return this->m_value.rbegin(); - } - - template - auto constexpr rbegin() const -> std::enable_if_t, - typename NewType::const_reverse_iterator> - { - return this->m_value.rbegin(); - } - - template - auto constexpr crbegin() const -> std::enable_if_t, - typename NewType::const_reverse_iterator> - { - return this->m_value.crbegin(); - } - - template * = nullptr> - auto constexpr end() - -> std::enable_if_t, typename NewType::iterator> - { - return this->m_value.end(); - } - - template - auto constexpr end() const -> std::enable_if_t, - typename NewType::const_iterator> - { - return this->m_value.end(); - } - - template - auto constexpr cend() const -> std::enable_if_t, - typename NewType::const_iterator> - { - return this->m_value.cend(); - } - - template * = nullptr> - auto constexpr rend() - -> std::enable_if_t, typename NewType::reverse_iterator> - { - return this->m_value.rend(); - } - - template - auto constexpr rend() const -> std::enable_if_t, - typename NewType::const_reverse_iterator> - { - return this->m_value.rend(); - } - - template - auto constexpr crend() const -> std::enable_if_t, - typename NewType::const_reverse_iterator> - { - return this->m_value.crend(); - } - }; - - template - auto constexpr - operator==(new_type const & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_equality_comparable_v) - -> std::enable_if_t, bool> - { - return lhs.decay() == rhs.decay(); - } - - template - auto constexpr operator==(new_type const & lhs, - BaseType const & rhs) noexcept(impl::is_nothrow_equality_comparable_v) - -> std::enable_if_t, bool> - { - return lhs.decay() == rhs; - } - - template - auto constexpr - operator==(BaseType const & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_equality_comparable_v) - -> std::enable_if_t, bool> - { - return lhs == rhs.decay(); - } - - template - auto constexpr - operator!=(new_type const & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_inequality_comparable_v) - -> std::enable_if_t, bool> - { - return lhs.decay() != rhs.decay(); - } - - template - auto constexpr operator!=(new_type const & lhs, - BaseType const & rhs) noexcept(impl::is_nothrow_inequality_comparable_v) - -> std::enable_if_t, bool> - { - return lhs.decay() != rhs; - } - - template - auto constexpr - operator!=(BaseType const & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_inequality_comparable_v) - -> std::enable_if_t, bool> - { - return lhs != rhs.decay(); - } - - template - auto constexpr - operator<(new_type const & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_less_than_comparable_v) - -> std::enable_if_t, bool> - { - return lhs.decay() < rhs.decay(); - } - - template - auto constexpr - operator>(new_type const & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_greater_than_comparable_v) - -> std::enable_if_t, bool> - { - return lhs.decay() > rhs.decay(); - } - - template - auto constexpr - operator<=(new_type const & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_less_than_equal_to_comparable_v) - -> std::enable_if_t, bool> - { - return lhs.decay() <= rhs.decay(); - } - - template - auto constexpr - operator>=(new_type const & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_greater_than_equal_to_comparable_v) - -> std::enable_if_t, bool> - { - return lhs.decay() >= rhs.decay(); - } - - template - auto operator<<(std::basic_ostream & output, new_type const & source) noexcept( - impl::is_nothrow_output_streamable_v, BaseType>) - -> std::enable_if_t, BaseType>, - std::basic_ostream> & - { - return output << source.decay(); - } - - template - auto operator>>(std::basic_istream & input, new_type & target) noexcept( - impl::is_nothrow_input_streamable_v, BaseType>) - -> std::enable_if_t, BaseType>, - std::basic_istream> & - { - return input >> target.m_value; - } - - template - auto constexpr - operator+(new_type const & lhs, new_type const & rhs) noexcept( - impl::is_nothrow_addable_v && std::is_nothrow_copy_constructible_v) - -> std::enable_if_t, new_type> - { - return {lhs.decay() + rhs.decay()}; - } - - template - auto constexpr operator+=(new_type & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_add_assignable_v) - -> std::enable_if_t, - new_type &> - { - lhs.m_value += rhs.m_value; - return lhs; - } - - template - auto constexpr - operator-(new_type const & lhs, new_type const & rhs) noexcept( - impl::is_nothrow_subtractable_v && std::is_nothrow_copy_constructible_v) - -> std::enable_if_t, new_type> - { - return {lhs.decay() - rhs.decay()}; - } - - template - auto constexpr - operator-=(new_type & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_subtract_assignable_v) - -> std::enable_if_t, - new_type &> - { - lhs.m_value -= rhs.m_value; - return lhs; - } - - template - auto constexpr - operator*(new_type const & lhs, new_type const & rhs) noexcept( - impl::is_nothrow_multipliable_v && std::is_nothrow_copy_constructible_v) - -> std::enable_if_t, new_type> - { - return {lhs.decay() * rhs.decay()}; - } - - template - auto constexpr - operator*=(new_type & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_multiply_assignable_v) - -> std::enable_if_t, - new_type &> - { - lhs.m_value *= rhs.m_value; - return lhs; - } - - template - auto constexpr - operator/(new_type const & lhs, new_type const & rhs) noexcept( - impl::is_nothrow_dividable_v && std::is_nothrow_copy_constructible_v) - -> std::enable_if_t, new_type> - { - return {lhs.decay() / rhs.decay()}; - } - - template - auto constexpr operator/=(new_type & lhs, - new_type const & rhs) noexcept(impl::is_nothrow_divide_assignable_v) - -> std::enable_if_t, - new_type &> - { - lhs.m_value /= rhs.m_value; - return lhs; - } - - template - auto constexpr begin(new_type & obj) - -> std::enable_if_t, - typename new_type::iterator> - { - return begin(obj.m_value); - } - - template - auto constexpr begin(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_iterator> - { - return begin(obj.m_value); - } - - template - auto constexpr cbegin(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_iterator> - { - return cbegin(obj.m_value); - } - - template - auto constexpr rbegin(new_type & obj) - -> std::enable_if_t, - typename new_type::reverse_iterator> - { - return rbegin(obj.m_value); - } - - template - auto constexpr rbegin(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_reverse_iterator> - { - return rbegin(obj.m_value); - } - - template - auto constexpr crbegin(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_reverse_iterator> - { - return crbegin(obj.m_value); - } - - template - auto constexpr end(new_type & obj) - -> std::enable_if_t, - typename new_type::iterator> - { - return end(obj.m_value); - } - - template - auto constexpr end(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_iterator> - { - return end(obj.m_value); - } - - template - auto constexpr cend(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_iterator> - { - return cend(obj.m_value); - } - - template - auto constexpr rend(new_type & obj) - -> std::enable_if_t, - typename new_type::reverse_iterator> - { - return rend(obj.m_value); - } - - template - auto constexpr rend(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_reverse_iterator> - { - return rend(obj.m_value); - } - - template - auto constexpr crend(new_type const & obj) - -> std::enable_if_t, - typename new_type::const_reverse_iterator> - { - return crend(obj.m_value); - } - -} // namespace nt - -namespace std -{ - template - struct hash> - { - template - auto constexpr operator()(nt::new_type const & object, - std::enable_if_t> * = nullptr) const - -> std::size_t - { - return std::hash{}(object.decay()); - } - }; -} // namespace std - -#endif diff --git a/source/include/newtype/version.hpp b/source/include/newtype/version.hpp deleted file mode 100644 index 8678514..0000000 --- a/source/include/newtype/version.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef NEWTYPE_VERSION_HPP -#define NEWTYPE_VERSION_HPP - -namespace nt -{ - - constexpr struct - { - int const major; - int const minor; - int const patch; - - char const * const name; - } version{ - .major = 1, - .minor = 1, - .patch = 0, - .name = "Anastasia", - }; - -} // namespace nt - -#endif \ No newline at end of file diff --git a/source/lib/CMakeLists.txt b/source/lib/CMakeLists.txt new file mode 100644 index 0000000..a1ed36e --- /dev/null +++ b/source/lib/CMakeLists.txt @@ -0,0 +1,21 @@ +add_library("${PROJECT_NAME}" INTERFACE) + +target_include_directories("${PROJECT_NAME}" INTERFACE + "$" + "$" +) + +target_compile_features("${PROJECT_NAME}" INTERFACE + "cxx_std_20" +) + +install(TARGETS "${PROJECT_NAME}" + EXPORT "${PROJECT_NAME}Targets" + PUBLIC_HEADER DESTINATION "include" +) + +install(DIRECTORY "${PROJECT_SOURCE_DIR}/include/" + DESTINATION "include" +) + +add_library("${PROJECT_NAME}::${PROJECT_NAME}" ALIAS "${PROJECT_NAME}") diff --git a/source/lib/include/newtype/derivable.hpp b/source/lib/include/newtype/derivable.hpp new file mode 100644 index 0000000..c798c59 --- /dev/null +++ b/source/lib/include/newtype/derivable.hpp @@ -0,0 +1,32 @@ +#ifndef NEWTYPE_DERIVABLE_HPP +#define NEWTYPE_DERIVABLE_HPP + +#include "newtype/version.hpp" + +namespace nt +{ + + template + struct derivable final + { + using tag_type = DerivableTag; + }; + + inline namespace derivables + { + + auto constexpr Arithmetic = derivable{}; + auto constexpr EqBase = derivable{}; + auto constexpr Hash = derivable{}; + auto constexpr ImplicitConversion = derivable{}; + auto constexpr Indirection = derivable{}; + auto constexpr Iterable = derivable{}; + auto constexpr Read = derivable{}; + auto constexpr Relational = derivable{}; + auto constexpr Show = derivable{}; + + } // namespace derivables + +} // namespace nt + +#endif \ No newline at end of file diff --git a/source/lib/include/newtype/derivation_clause.hpp b/source/lib/include/newtype/derivation_clause.hpp new file mode 100644 index 0000000..6de70e1 --- /dev/null +++ b/source/lib/include/newtype/derivation_clause.hpp @@ -0,0 +1,70 @@ +#ifndef NEWTYPE_DERIVATION_CLAUSE_HPP +#define NEWTYPE_DERIVATION_CLAUSE_HPP + +#include "newtype/derivable.hpp" +#include "newtype/version.hpp" + +#include + +namespace nt +{ + + template + struct derivation_clause + { + constexpr derivation_clause(derivable...) noexcept + { + } + + template + auto constexpr operator()(derivable) const noexcept -> bool + { + return (std::is_same_v || ...); + } + + template + auto constexpr operator()(derivable, derivable...) const noexcept -> bool + { + return (*this)(derivable{}) && (*this)(derivable{}...); + } + + template + auto constexpr operator<(derivation_clause other) const noexcept -> bool + { + return (sizeof...(DerivableTags) < sizeof...(OtherDerivableTags)) && other(derivable{}...); + } + + template + auto constexpr operator>(derivation_clause other) const noexcept -> bool + { + return other < *this; + } + + template + auto constexpr operator==(derivation_clause other) const noexcept -> bool + { + return sizeof...(DerivableTags) == sizeof...(OtherDerivableTags) && other(derivable{}...); + } + + template + auto constexpr operator!=(derivation_clause other) const noexcept -> bool + { + return !(*this == other); + } + + template + auto constexpr operator<=(derivation_clause other) const noexcept -> bool + { + return *this < other || *this == other; + } + + template + auto constexpr operator>=(derivation_clause other) const noexcept -> bool + { + return *this > other || *this == other; + } + }; + +} // namespace nt + +#endif \ No newline at end of file diff --git a/source/lib/include/newtype/deriving.hpp b/source/lib/include/newtype/deriving.hpp new file mode 100644 index 0000000..ae10bab --- /dev/null +++ b/source/lib/include/newtype/deriving.hpp @@ -0,0 +1,21 @@ +#ifndef NEWTYPE_DERIVING_HPP +#define NEWTYPE_DERIVING_HPP + +#include "newtype/derivable.hpp" +#include "newtype/derivation_clause.hpp" +#include "newtype/version.hpp" + +#include + +namespace nt +{ + + template + auto constexpr deriving(derivable... features) noexcept -> derivation_clause + { + return {features...}; + } + +} // namespace nt + +#endif \ No newline at end of file diff --git a/source/lib/include/newtype/impl/new_type_iterator_types.hpp b/source/lib/include/newtype/impl/new_type_iterator_types.hpp new file mode 100644 index 0000000..2ea8274 --- /dev/null +++ b/source/lib/include/newtype/impl/new_type_iterator_types.hpp @@ -0,0 +1,66 @@ +#ifndef NEWTYPE_IMPL_NEW_TYPE_ITERATOR_TYPES_HPP +#define NEWTYPE_IMPL_NEW_TYPE_ITERATOR_TYPES_HPP + +#include "newtype/version.hpp" + +#include + +namespace nt::impl +{ + + template> + struct new_type_iterator + { + }; + + template + struct new_type_iterator> + { + using iterator = typename T::iterator; + }; + + template> + struct new_type_const_iterator + { + }; + + template + struct new_type_const_iterator> + { + using const_iterator = typename T::const_iterator; + }; + + template> + struct new_type_reverse_iterator + { + }; + + template + struct new_type_reverse_iterator> + { + using reverse_iterator = typename T::reverse_iterator; + }; + + template> + struct new_type_const_reverse_iterator + { + }; + + template + struct new_type_const_reverse_iterator> + { + using const_reverse_iterator = typename T::const_reverse_iterator; + }; + + template + struct new_type_iterator_types + : new_type_iterator + , new_type_const_iterator + , new_type_reverse_iterator + , new_type_const_reverse_iterator + { + }; + +} // namespace nt::impl + +#endif \ No newline at end of file diff --git a/source/lib/include/newtype/impl/new_type_storage.hpp b/source/lib/include/newtype/impl/new_type_storage.hpp new file mode 100644 index 0000000..f7842af --- /dev/null +++ b/source/lib/include/newtype/impl/new_type_storage.hpp @@ -0,0 +1,139 @@ +#ifndef NEWTYPE_IMPL_NEW_TYPE_STORAGE_HPP +#define NEWTYPE_IMPL_NEW_TYPE_STORAGE_HPP + +#include "newtype/version.hpp" + +#include +#include + +namespace nt::impl +{ + + template + struct new_type_storage + { + constexpr new_type_storage() noexcept(std::is_nothrow_default_constructible_v) + : m_value{} + { + } + + constexpr new_type_storage(BaseType const & value) + : m_value{value} + { + } + + constexpr new_type_storage(BaseType && value) + : m_value{std::move(value)} + { + } + + BaseType m_value; + }; + + template> + struct new_type_constructor : new_type_storage + { + using new_type_storage::new_type_storage; + }; + + template + struct new_type_constructor : new_type_storage + { + using new_type_storage::new_type_storage; + + constexpr new_type_constructor() = delete; + }; + + template> + struct new_type_copy_constructor : new_type_constructor + { + using new_type_constructor::new_type_constructor; + + constexpr new_type_copy_constructor(new_type_copy_constructor const &) = default; + constexpr new_type_copy_constructor(new_type_copy_constructor &&) = default; + auto constexpr operator=(new_type_copy_constructor &) -> new_type_copy_constructor & = default; + auto constexpr operator=(new_type_copy_constructor &&) -> new_type_copy_constructor & = default; + }; + + template + struct new_type_copy_constructor : new_type_constructor + { + using new_type_constructor::new_type_constructor; + + constexpr new_type_copy_constructor(new_type_copy_constructor const &) = delete; + constexpr new_type_copy_constructor(new_type_copy_constructor &&) = default; + constexpr new_type_copy_constructor(BaseType const &) = delete; + auto constexpr operator=(new_type_copy_constructor &) -> new_type_copy_constructor & = default; + auto constexpr operator=(new_type_copy_constructor &&) -> new_type_copy_constructor & = default; + }; + + template> + struct new_type_move_constructor : new_type_copy_constructor + { + using new_type_copy_constructor::new_type_copy_constructor; + + constexpr new_type_move_constructor(new_type_move_constructor const &) = default; + constexpr new_type_move_constructor(new_type_move_constructor &&) = default; + auto constexpr operator=(new_type_move_constructor &) -> new_type_move_constructor & = default; + auto constexpr operator=(new_type_move_constructor &&) -> new_type_move_constructor & = default; + }; + + template + struct new_type_move_constructor : new_type_copy_constructor + { + using new_type_copy_constructor::new_type_copy_constructor; + + constexpr new_type_move_constructor(new_type_move_constructor const &) = default; + constexpr new_type_move_constructor(new_type_move_constructor &&) = delete; + constexpr new_type_move_constructor(BaseType &&) = delete; + auto constexpr operator=(new_type_move_constructor &) -> new_type_move_constructor & = default; + auto constexpr operator=(new_type_move_constructor &&) -> new_type_move_constructor & = default; + }; + + template> + struct new_type_copy_assignment : new_type_move_constructor + { + using new_type_move_constructor::new_type_move_constructor; + + constexpr new_type_copy_assignment(new_type_copy_assignment const &) = default; + constexpr new_type_copy_assignment(new_type_copy_assignment &&) = default; + auto constexpr operator=(new_type_copy_assignment &) -> new_type_copy_assignment & = default; + auto constexpr operator=(new_type_copy_assignment &&) -> new_type_copy_assignment & = default; + }; + + template + struct new_type_copy_assignment : new_type_move_constructor + { + using new_type_move_constructor::new_type_move_constructor; + + constexpr new_type_copy_assignment(new_type_copy_assignment const &) = default; + constexpr new_type_copy_assignment(new_type_copy_assignment &&) = default; + auto constexpr operator=(new_type_copy_assignment &) -> new_type_copy_assignment & = default; + auto constexpr operator=(new_type_copy_assignment &&) -> new_type_copy_assignment & = delete; + }; + + template> + struct new_type_move_assignment : new_type_copy_assignment + { + using new_type_copy_assignment::new_type_copy_assignment; + + constexpr new_type_move_assignment(new_type_move_assignment const &) = default; + constexpr new_type_move_assignment(new_type_move_assignment &&) = default; + auto constexpr operator=(new_type_move_assignment &) -> new_type_move_assignment & = default; + auto constexpr operator=(new_type_move_assignment &&) -> new_type_move_assignment & = default; + }; + + template + struct new_type_move_assignment : new_type_copy_assignment + { + using new_type_copy_assignment::new_type_copy_assignment; + + constexpr new_type_move_assignment(new_type_move_assignment const &) = default; + constexpr new_type_move_assignment(new_type_move_assignment &&) = default; + auto constexpr operator=(new_type_move_assignment &) -> new_type_move_assignment & = default; + auto constexpr operator=(new_type_move_assignment &&) -> new_type_move_assignment & = delete; + }; + +} // namespace nt::impl + +#endif diff --git a/source/lib/include/newtype/impl/type_traits_extensions.hpp b/source/lib/include/newtype/impl/type_traits_extensions.hpp new file mode 100644 index 0000000..dc41649 --- /dev/null +++ b/source/lib/include/newtype/impl/type_traits_extensions.hpp @@ -0,0 +1,853 @@ +#ifndef NEWTYPE_IMPL_TYPE_TRAITS_EXTENSIONS_HPP +#define NEWTYPE_IMPL_TYPE_TRAITS_EXTENSIONS_HPP + +#include "newtype/version.hpp" + +#include +#include +#include +#include + +namespace nt::impl +{ + + inline namespace equality_comparable + { + + template + struct is_equality_comparable : std::false_type + { + }; + + template + struct is_equality_comparable() == std::declval())>> : std::true_type + { + }; + + template + auto constexpr is_equality_comparable_v = is_equality_comparable::value; + + template + struct is_nothrow_equality_comparable : std::false_type + { + }; + + template + struct is_nothrow_equality_comparable() == std::declval())>> + : std::bool_constant() == std::declval())> + { + }; + + template + auto constexpr is_nothrow_equality_comparable_v = is_nothrow_equality_comparable::value; + + template + struct is_inequality_comparable : std::false_type + { + }; + + template + struct is_inequality_comparable() != std::declval())>> : std::true_type + { + }; + + template + auto constexpr is_inequality_comparable_v = is_inequality_comparable::value; + + template + struct is_nothrow_inequality_comparable : std::false_type + { + }; + + template + struct is_nothrow_inequality_comparable() != std::declval())>> + : std::bool_constant() != std::declval())> + { + }; + + template + auto constexpr is_nothrow_inequality_comparable_v = is_nothrow_inequality_comparable::value; + + } // namespace equality_comparable + + inline namespace relationally_comparable + { + + template + struct is_less_than_comparable : std::false_type + { + }; + + template + struct is_less_than_comparable() < std::declval())>> : std::true_type + { + }; + + template + auto constexpr is_less_than_comparable_v = is_less_than_comparable::value; + + template + struct is_nothrow_less_than_comparable : std::false_type + { + }; + + template + struct is_nothrow_less_than_comparable() < std::declval())>> + : std::bool_constant() < std::declval())> + { + }; + + template + auto constexpr is_nothrow_less_than_comparable_v = is_nothrow_less_than_comparable::value; + + template + struct is_greater_than_comparable : std::false_type + { + }; + + template + struct is_greater_than_comparable() > std::declval())>> : std::true_type + { + }; + + template + auto constexpr is_greater_than_comparable_v = is_greater_than_comparable::value; + + template + struct is_nothrow_greater_than_comparable : std::false_type + { + }; + + template + struct is_nothrow_greater_than_comparable() > std::declval())>> + : std::bool_constant() > std::declval())> + { + }; + + template + auto constexpr is_nothrow_greater_than_comparable_v = is_nothrow_greater_than_comparable::value; + + template + struct is_less_than_equal_to_comparable : std::false_type + { + }; + + template + struct is_less_than_equal_to_comparable() <= std::declval())>> : std::true_type + { + }; + + template + auto constexpr is_less_than_equal_to_comparable_v = is_less_than_equal_to_comparable::value; + + template + struct is_nothrow_less_than_equal_to_comparable : std::false_type + { + }; + + template + struct is_nothrow_less_than_equal_to_comparable() <= std::declval())>> + : std::bool_constant() <= std::declval())> + { + }; + + template + auto constexpr is_nothrow_less_than_equal_to_comparable_v = is_nothrow_less_than_equal_to_comparable::value; + + template + struct is_greater_than_equal_to_comparable : std::false_type + { + }; + + template + struct is_greater_than_equal_to_comparable() >= std::declval())>> + : std::true_type + { + }; + + template + auto constexpr is_greater_than_equal_to_comparable_v = is_greater_than_equal_to_comparable::value; + + template + struct is_nothrow_greater_than_equal_to_comparable : std::false_type + { + }; + + template + struct is_nothrow_greater_than_equal_to_comparable() >= std::declval())>> + : std::bool_constant() >= std::declval())> + { + }; + + template + auto constexpr is_nothrow_greater_than_equal_to_comparable_v = is_nothrow_greater_than_equal_to_comparable::value; + } // namespace relationally_comparable + + inline namespace iostreamable + { + + template + struct is_output_streamable : std::false_type + { + }; + + template + struct is_output_streamable() << std::declval())>> + : std::true_type + { + }; + + template + auto constexpr is_output_streamable_v = is_output_streamable::value; + + template + struct is_nothrow_output_streamable : std::false_type + { + }; + + template + struct is_nothrow_output_streamable() << std::declval())>> + : std::bool_constant() << std::declval())> + { + }; + + template + auto constexpr is_nothrow_output_streamable_v = is_nothrow_output_streamable::value; + + template + struct is_input_streamable : std::false_type + { + }; + + template + struct is_input_streamable() >> std::declval())>> : std::true_type + { + }; + + template + auto constexpr is_input_streamable_v = is_input_streamable::value; + + template + struct is_nothrow_input_streamable : std::false_type + { + }; + + template + struct is_nothrow_input_streamable() >> std::declval())>> + : std::bool_constant() >> std::declval())> + { + }; + + template + auto constexpr is_nothrow_input_streamable_v = is_nothrow_input_streamable::value; + + } // namespace iostreamable + + inline namespace arithmetic + { + + template + struct is_addable : std::false_type + { + }; + + template + struct is_addable() + std::declval())>> : std::true_type + { + }; + + template + auto constexpr is_addable_v = is_addable::value; + + template + struct is_nothrow_addable : std::false_type + { + }; + + template + struct is_nothrow_addable() + std::declval())>> + : std::bool_constant() + std::declval())> + { + }; + + template + auto constexpr is_nothrow_addable_v = is_nothrow_addable::value; + + template + struct is_subtractable : std::false_type + { + }; + + template + struct is_subtractable() - std::declval())>> : std::true_type + { + }; + + template + auto constexpr is_subtractable_v = is_subtractable::value; + + template + struct is_nothrow_subtractable : std::false_type + { + }; + + template + struct is_nothrow_subtractable() - std::declval())>> + : std::bool_constant() - std::declval())> + { + }; + + template + auto constexpr is_nothrow_subtractable_v = is_nothrow_subtractable::value; + + template + struct is_multipliable : std::false_type + { + }; + + template + struct is_multipliable() * std::declval())>> : std::true_type + { + }; + + template + auto constexpr is_multipliable_v = is_multipliable::value; + + template + struct is_nothrow_multipliable : std::false_type + { + }; + + template + struct is_nothrow_multipliable() * std::declval())>> + : std::bool_constant() * std::declval())> + { + }; + + template + auto constexpr is_nothrow_multipliable_v = is_nothrow_multipliable::value; + + template + struct is_dividable : std::false_type + { + }; + + template + struct is_dividable() / std::declval())>> : std::true_type + { + }; + + template + auto constexpr is_dividable_v = is_dividable::value; + + template + struct is_nothrow_dividable : std::false_type + { + }; + + template + struct is_nothrow_dividable() / std::declval())>> + : std::bool_constant() / std::declval())> + { + }; + + template + auto constexpr is_nothrow_dividable_v = is_nothrow_dividable::value; + + } // namespace arithmetic + + inline namespace compound_arithmetic + { + + template + struct is_add_assignable : std::false_type + { + }; + + template + struct is_add_assignable() += std::declval())>> : std::true_type + { + }; + + template + auto constexpr is_add_assignable_v = is_add_assignable::value; + + template + struct is_nothrow_add_assignable : std::false_type + { + }; + + template + struct is_nothrow_add_assignable() += std::declval())>> + : std::bool_constant() += std::declval())> + { + }; + + template + auto constexpr is_nothrow_add_assignable_v = is_nothrow_add_assignable::value; + + template + struct is_subtract_assignable : std::false_type + { + }; + + template + struct is_subtract_assignable() -= std::declval())>> : std::true_type + { + }; + + template + auto constexpr is_subtract_assignable_v = is_subtract_assignable::value; + + template + struct is_nothrow_subtract_assignable : std::false_type + { + }; + + template + struct is_nothrow_subtract_assignable() -= std::declval())>> + : std::bool_constant() -= std::declval())> + { + }; + + template + auto constexpr is_nothrow_subtract_assignable_v = is_nothrow_subtract_assignable::value; + + template + struct is_multiply_assignable : std::false_type + { + }; + + template + struct is_multiply_assignable() *= std::declval())>> : std::true_type + { + }; + + template + auto constexpr is_multiply_assignable_v = is_multiply_assignable::value; + + template + struct is_nothrow_multiply_assignable : std::false_type + { + }; + + template + struct is_nothrow_multiply_assignable() *= std::declval())>> + : std::bool_constant() *= std::declval())> + { + }; + + template + auto constexpr is_nothrow_multiply_assignable_v = is_nothrow_multiply_assignable::value; + + template + struct is_divide_assignable : std::false_type + { + }; + + template + struct is_divide_assignable() /= std::declval())>> : std::true_type + { + }; + + template + auto constexpr is_divide_assignable_v = is_divide_assignable::value; + + template + struct is_nothrow_divide_assignable : std::false_type + { + }; + + template + struct is_nothrow_divide_assignable() /= std::declval())>> + : std::bool_constant() /= std::declval())> + { + }; + + template + auto constexpr is_nothrow_divide_assignable_v = is_nothrow_divide_assignable::value; + + } // namespace compound_arithmetic + + inline namespace std_support + { + + template + struct is_hashable : std::false_type + { + }; + + template + struct is_hashable const &>()(std::declval()))>> + : std::is_same const &>()(std::declval()))> + { + }; + + template + auto constexpr is_hashable_v = is_hashable::value; + + } // namespace std_support + + inline namespace iterable_begin + { + template + struct has_free_begin : std::false_type + { + }; + + template + struct has_free_begin()))>> + : std::is_same()))>> + { + }; + + template + struct has_free_begin()))>> + : std::is_same()))>> + { + }; + + template + auto constexpr has_free_begin_v = has_free_begin::value; + + template + struct has_member_begin : std::false_type + { + }; + + template + struct has_member_begin().begin())>> + : std::is_same().begin())>> + { + }; + + template + struct has_member_begin().begin())>> + : std::is_same().begin())>> + { + }; + + template + auto constexpr has_member_begin_v = has_member_begin::value; + + template + struct has_begin : std::disjunction, has_member_begin> + { + }; + + template + auto constexpr has_begin_v = has_begin::value; + } // namespace iterable_begin + + inline namespace iterable_cbegin + { + template + struct has_free_cbegin : std::false_type + { + }; + + template + struct has_free_cbegin()))>> + : std::is_same()))>> + { + }; + + template + auto constexpr has_free_cbegin_v = has_free_cbegin::value; + + template + struct has_member_cbegin : std::false_type + { + }; + + template + struct has_member_cbegin().cbegin())>> + : std::is_same().cbegin())> + { + }; + + template + auto constexpr has_member_cbegin_v = has_member_cbegin::value; + + template + struct has_cbegin : std::disjunction, has_member_cbegin> + { + }; + + template + auto constexpr has_cbegin_v = has_cbegin::value; + } // namespace iterable_cbegin + + inline namespace iterable_rbegin + { + template + struct has_free_rbegin : std::false_type + { + }; + + template + struct has_free_rbegin()))>> + : std::is_same()))>> + { + }; + + template + struct has_free_rbegin()))>> + : std::is_same()))>> + { + }; + + template + auto constexpr has_free_rbegin_v = has_free_rbegin::value; + + template + struct has_member_rbegin : std::false_type + { + }; + + template + struct has_member_rbegin().rbegin())>> + : std::is_same().rbegin())>> + { + }; + + template + struct has_member_rbegin().rbegin())>> + : std::is_same().rbegin())>> + { + }; + + template + auto constexpr has_member_rbegin_v = has_member_rbegin::value; + + template + struct has_rbegin : std::disjunction, has_member_rbegin> + { + }; + + template + auto constexpr has_rbegin_v = has_rbegin::value; + } // namespace iterable_rbegin + + inline namespace iterable_crbegin + { + template + struct has_free_crbegin : std::false_type + { + }; + + template + struct has_free_crbegin()))>> + : std::is_same()))>> + { + }; + + template + auto constexpr has_free_crbegin_v = has_free_crbegin::value; + + template + struct has_member_crbegin : std::false_type + { + }; + + template + struct has_member_crbegin().crbegin())>> + : std::is_same().crbegin())>> + { + }; + + template + auto constexpr has_member_crbegin_v = has_member_crbegin::value; + + template + struct has_crbegin : std::disjunction, has_member_crbegin> + { + }; + + template + auto constexpr has_crbegin_v = has_crbegin::value; + } // namespace iterable_crbegin + + inline namespace iterable_end + { + template + struct has_free_end : std::false_type + { + }; + + template + struct has_free_end()))>> + : std::is_same()))>> + { + }; + + template + struct has_free_end()))>> + : std::is_same()))>> + { + }; + + template + auto constexpr has_free_end_v = has_free_end::value; + + template + struct has_member_end : std::false_type + { + }; + + template + struct has_member_end().end())>> + : std::is_same().end())>> + { + }; + + template + struct has_member_end().end())>> + : std::is_same().end())>> + { + }; + + template + auto constexpr has_member_end_v = has_member_end::value; + + template + struct has_end : std::disjunction, has_member_end> + { + }; + + template + auto constexpr has_end_v = has_end::value; + } // namespace iterable_end + + inline namespace iterable_cend + { + template + struct has_free_cend : std::false_type + { + }; + + template + struct has_free_cend()))>> + : std::is_same()))>> + { + }; + + template + auto constexpr has_free_cend_v = has_free_cend::value; + + template + struct has_member_cend : std::false_type + { + }; + + template + struct has_member_cend().cend())>> + : std::is_same().cend())> + { + }; + + template + auto constexpr has_member_cend_v = has_member_cend::value; + + template + struct has_cend : std::disjunction, has_member_cend> + { + }; + + template + auto constexpr has_cend_v = has_cend::value; + } // namespace iterable_cend + + inline namespace iterable_rend + { + template + struct has_free_rend : std::false_type + { + }; + + template + struct has_free_rend()))>> + : std::is_same()))>> + { + }; + + template + struct has_free_rend()))>> + : std::is_same()))>> + { + }; + + template + auto constexpr has_free_rend_v = has_free_rend::value; + + template + struct has_member_rend : std::false_type + { + }; + + template + struct has_member_rend().rend())>> + : std::is_same().rend())>> + { + }; + + template + struct has_member_rend().rend())>> + : std::is_same().rend())>> + { + }; + + template + auto constexpr has_member_rend_v = has_member_rend::value; + + template + struct has_rend : std::disjunction, has_member_rend> + { + }; + + template + auto constexpr has_rend_v = has_rend::value; + } // namespace iterable_rend + + inline namespace iterable_crend + { + template + struct has_free_crend : std::false_type + { + }; + + template + struct has_free_crend()))>> + : std::is_same()))>> + { + }; + + template + auto constexpr has_free_crend_v = has_free_crend::value; + + template + struct has_member_crend : std::false_type + { + }; + + template + struct has_member_crend().crend())>> + : std::is_same().crend())>> + { + }; + + template + auto constexpr has_member_crend_v = has_member_crend::value; + + template + struct has_crend : std::disjunction, has_member_crend> + { + }; + + template + auto constexpr has_crend_v = has_crend::value; + } // namespace iterable_crend + +} // namespace nt::impl + +#endif \ No newline at end of file diff --git a/source/lib/include/newtype/newtype.hpp b/source/lib/include/newtype/newtype.hpp new file mode 100644 index 0000000..e2704f3 --- /dev/null +++ b/source/lib/include/newtype/newtype.hpp @@ -0,0 +1,550 @@ +#ifndef NEWTYPE_NEWTYPE_HPP +#define NEWTYPE_NEWTYPE_HPP + +#include "newtype/derivable.hpp" +#include "newtype/deriving.hpp" +#include "newtype/impl/new_type_iterator_types.hpp" +#include "newtype/impl/new_type_storage.hpp" +#include "newtype/impl/type_traits_extensions.hpp" +#include "newtype/version.hpp" + +#include +#include +#include +#include + +namespace nt +{ + + template + class new_type + : impl::new_type_move_assignment + , public impl::new_type_iterator_types + { + static_assert(!std::is_reference_v, "The base type must not be a reference type"); + static_assert(!std::is_void_v>, "The base type must not be possibly cv-qualified void"); + + template + auto friend operator>>(std::basic_istream &, new_type &) noexcept( + impl::is_nothrow_input_streamable_v, BaseTypeT>) + -> std::enable_if_t, BaseTypeT>, + std::basic_istream> &; + + template + auto constexpr friend + operator+=(new_type & lhs, + new_type const & rhs) noexcept(impl::is_nothrow_add_assignable_v) + -> std::enable_if_t, + new_type &>; + + template + auto constexpr friend + operator-=(new_type & lhs, + new_type const & rhs) noexcept(impl::is_nothrow_subtract_assignable_v) + -> std::enable_if_t, + new_type &>; + + template + auto constexpr friend + operator*=(new_type & lhs, + new_type const & rhs) noexcept(impl::is_nothrow_multiply_assignable_v) + -> std::enable_if_t, + new_type &>; + + template + auto constexpr friend + operator/=(new_type & lhs, + new_type const & rhs) noexcept(impl::is_nothrow_divide_assignable_v) + -> std::enable_if_t, + new_type &>; + + template + auto constexpr friend begin(new_type & obj) + -> std::enable_if_t, + typename new_type::iterator>; + + template + auto constexpr friend begin(new_type const & obj) + -> std::enable_if_t, + typename new_type::const_iterator>; + + template + auto constexpr friend cbegin(new_type const & obj) + -> std::enable_if_t, + typename new_type::const_iterator>; + + template + auto constexpr friend rbegin(new_type & obj) + -> std::enable_if_t, + typename new_type::reverse_iterator>; + + template + auto constexpr friend rbegin(new_type const & obj) + -> std::enable_if_t, + typename new_type::const_reverse_iterator>; + + template + auto constexpr friend crbegin(new_type const & obj) + -> std::enable_if_t, + typename new_type::const_reverse_iterator>; + + template + auto constexpr friend end(new_type & obj) + -> std::enable_if_t, + typename new_type::iterator>; + + template + auto constexpr friend end(new_type const & obj) + -> std::enable_if_t, + typename new_type::const_iterator>; + + template + auto constexpr friend cend(new_type const & obj) + -> std::enable_if_t, + typename new_type::const_iterator>; + + template + auto constexpr friend rend(new_type & obj) + -> std::enable_if_t, + typename new_type::reverse_iterator>; + + template + auto constexpr friend rend(new_type const & obj) + -> std::enable_if_t, + typename new_type::const_reverse_iterator>; + + template + auto constexpr friend crend(new_type const & obj) + -> std::enable_if_t, + typename new_type::const_reverse_iterator>; + + using super = impl::new_type_move_assignment; + + public: + using base_type = BaseType; + using tag_type = TagType; + using derivation_clause_type = decltype(DerivationClause); + + auto constexpr static derivation_clause = DerivationClause; + + using super::super; + + constexpr new_type() noexcept(std::is_nothrow_default_constructible_v) = default; + constexpr new_type(new_type const &) noexcept(std::is_nothrow_copy_constructible_v) = default; + constexpr new_type(new_type &&) noexcept(std::is_nothrow_move_constructible_v) = default; + + auto constexpr operator=(new_type const &) noexcept(std::is_nothrow_copy_assignable_v) -> new_type & = default; + auto constexpr operator=(new_type &&) noexcept(std::is_nothrow_move_assignable_v) -> new_type & = default; + + auto constexpr decay() const noexcept(std::is_nothrow_copy_constructible_v) -> BaseType + { + return this->m_value; + } + + template * = nullptr> + constexpr operator base_type() const noexcept(std::is_nothrow_copy_constructible_v) + { + return decay(); + } + + template * = nullptr> + explicit constexpr operator base_type() const noexcept(std::is_nothrow_copy_constructible_v) + { + return decay(); + } + + template + auto constexpr operator->() noexcept -> std::enable_if_t + { + return std::addressof(this->m_value); + } + + template + auto constexpr operator->() const noexcept -> std::enable_if_t + { + return std::addressof(this->m_value); + } + + template * = nullptr> + auto constexpr begin() + -> std::enable_if_t, typename NewType::iterator> + { + return this->m_value.begin(); + } + + template + auto constexpr begin() const -> std::enable_if_t, + typename NewType::const_iterator> + { + return this->m_value.begin(); + } + + template + auto constexpr cbegin() const -> std::enable_if_t, + typename NewType::const_iterator> + { + return this->m_value.cbegin(); + } + + template * = nullptr> + auto constexpr rbegin() + -> std::enable_if_t, typename NewType::reverse_iterator> + { + return this->m_value.rbegin(); + } + + template + auto constexpr rbegin() const -> std::enable_if_t, + typename NewType::const_reverse_iterator> + { + return this->m_value.rbegin(); + } + + template + auto constexpr crbegin() const -> std::enable_if_t, + typename NewType::const_reverse_iterator> + { + return this->m_value.crbegin(); + } + + template * = nullptr> + auto constexpr end() + -> std::enable_if_t, typename NewType::iterator> + { + return this->m_value.end(); + } + + template + auto constexpr end() const -> std::enable_if_t, + typename NewType::const_iterator> + { + return this->m_value.end(); + } + + template + auto constexpr cend() const -> std::enable_if_t, + typename NewType::const_iterator> + { + return this->m_value.cend(); + } + + template * = nullptr> + auto constexpr rend() + -> std::enable_if_t, typename NewType::reverse_iterator> + { + return this->m_value.rend(); + } + + template + auto constexpr rend() const -> std::enable_if_t, + typename NewType::const_reverse_iterator> + { + return this->m_value.rend(); + } + + template + auto constexpr crend() const -> std::enable_if_t, + typename NewType::const_reverse_iterator> + { + return this->m_value.crend(); + } + }; + + template + auto constexpr + operator==(new_type const & lhs, + new_type const & rhs) noexcept(impl::is_nothrow_equality_comparable_v) + -> std::enable_if_t, bool> + { + return lhs.decay() == rhs.decay(); + } + + template + auto constexpr operator==(new_type const & lhs, + BaseType const & rhs) noexcept(impl::is_nothrow_equality_comparable_v) + -> std::enable_if_t, bool> + { + return lhs.decay() == rhs; + } + + template + auto constexpr + operator==(BaseType const & lhs, + new_type const & rhs) noexcept(impl::is_nothrow_equality_comparable_v) + -> std::enable_if_t, bool> + { + return lhs == rhs.decay(); + } + + template + auto constexpr + operator!=(new_type const & lhs, + new_type const & rhs) noexcept(impl::is_nothrow_inequality_comparable_v) + -> std::enable_if_t, bool> + { + return lhs.decay() != rhs.decay(); + } + + template + auto constexpr operator!=(new_type const & lhs, + BaseType const & rhs) noexcept(impl::is_nothrow_inequality_comparable_v) + -> std::enable_if_t, bool> + { + return lhs.decay() != rhs; + } + + template + auto constexpr + operator!=(BaseType const & lhs, + new_type const & rhs) noexcept(impl::is_nothrow_inequality_comparable_v) + -> std::enable_if_t, bool> + { + return lhs != rhs.decay(); + } + + template + auto constexpr + operator<(new_type const & lhs, + new_type const & rhs) noexcept(impl::is_nothrow_less_than_comparable_v) + -> std::enable_if_t, bool> + { + return lhs.decay() < rhs.decay(); + } + + template + auto constexpr + operator>(new_type const & lhs, + new_type const & rhs) noexcept(impl::is_nothrow_greater_than_comparable_v) + -> std::enable_if_t, bool> + { + return lhs.decay() > rhs.decay(); + } + + template + auto constexpr + operator<=(new_type const & lhs, + new_type const & rhs) noexcept(impl::is_nothrow_less_than_equal_to_comparable_v) + -> std::enable_if_t, bool> + { + return lhs.decay() <= rhs.decay(); + } + + template + auto constexpr + operator>=(new_type const & lhs, + new_type const & rhs) noexcept(impl::is_nothrow_greater_than_equal_to_comparable_v) + -> std::enable_if_t, bool> + { + return lhs.decay() >= rhs.decay(); + } + + template + auto operator<<(std::basic_ostream & output, new_type const & source) noexcept( + impl::is_nothrow_output_streamable_v, BaseType>) + -> std::enable_if_t, BaseType>, + std::basic_ostream> & + { + return output << source.decay(); + } + + template + auto operator>>(std::basic_istream & input, new_type & target) noexcept( + impl::is_nothrow_input_streamable_v, BaseType>) + -> std::enable_if_t, BaseType>, + std::basic_istream> & + { + return input >> target.m_value; + } + + template + auto constexpr + operator+(new_type const & lhs, new_type const & rhs) noexcept( + impl::is_nothrow_addable_v && std::is_nothrow_copy_constructible_v) + -> std::enable_if_t, new_type> + { + return {lhs.decay() + rhs.decay()}; + } + + template + auto constexpr operator+=(new_type & lhs, + new_type const & rhs) noexcept(impl::is_nothrow_add_assignable_v) + -> std::enable_if_t, + new_type &> + { + lhs.m_value += rhs.m_value; + return lhs; + } + + template + auto constexpr + operator-(new_type const & lhs, new_type const & rhs) noexcept( + impl::is_nothrow_subtractable_v && std::is_nothrow_copy_constructible_v) + -> std::enable_if_t, new_type> + { + return {lhs.decay() - rhs.decay()}; + } + + template + auto constexpr + operator-=(new_type & lhs, + new_type const & rhs) noexcept(impl::is_nothrow_subtract_assignable_v) + -> std::enable_if_t, + new_type &> + { + lhs.m_value -= rhs.m_value; + return lhs; + } + + template + auto constexpr + operator*(new_type const & lhs, new_type const & rhs) noexcept( + impl::is_nothrow_multipliable_v && std::is_nothrow_copy_constructible_v) + -> std::enable_if_t, new_type> + { + return {lhs.decay() * rhs.decay()}; + } + + template + auto constexpr + operator*=(new_type & lhs, + new_type const & rhs) noexcept(impl::is_nothrow_multiply_assignable_v) + -> std::enable_if_t, + new_type &> + { + lhs.m_value *= rhs.m_value; + return lhs; + } + + template + auto constexpr + operator/(new_type const & lhs, new_type const & rhs) noexcept( + impl::is_nothrow_dividable_v && std::is_nothrow_copy_constructible_v) + -> std::enable_if_t, new_type> + { + return {lhs.decay() / rhs.decay()}; + } + + template + auto constexpr operator/=(new_type & lhs, + new_type const & rhs) noexcept(impl::is_nothrow_divide_assignable_v) + -> std::enable_if_t, + new_type &> + { + lhs.m_value /= rhs.m_value; + return lhs; + } + + template + auto constexpr begin(new_type & obj) + -> std::enable_if_t, + typename new_type::iterator> + { + return begin(obj.m_value); + } + + template + auto constexpr begin(new_type const & obj) + -> std::enable_if_t, + typename new_type::const_iterator> + { + return begin(obj.m_value); + } + + template + auto constexpr cbegin(new_type const & obj) + -> std::enable_if_t, + typename new_type::const_iterator> + { + return cbegin(obj.m_value); + } + + template + auto constexpr rbegin(new_type & obj) + -> std::enable_if_t, + typename new_type::reverse_iterator> + { + return rbegin(obj.m_value); + } + + template + auto constexpr rbegin(new_type const & obj) + -> std::enable_if_t, + typename new_type::const_reverse_iterator> + { + return rbegin(obj.m_value); + } + + template + auto constexpr crbegin(new_type const & obj) + -> std::enable_if_t, + typename new_type::const_reverse_iterator> + { + return crbegin(obj.m_value); + } + + template + auto constexpr end(new_type & obj) + -> std::enable_if_t, + typename new_type::iterator> + { + return end(obj.m_value); + } + + template + auto constexpr end(new_type const & obj) + -> std::enable_if_t, + typename new_type::const_iterator> + { + return end(obj.m_value); + } + + template + auto constexpr cend(new_type const & obj) + -> std::enable_if_t, + typename new_type::const_iterator> + { + return cend(obj.m_value); + } + + template + auto constexpr rend(new_type & obj) + -> std::enable_if_t, + typename new_type::reverse_iterator> + { + return rend(obj.m_value); + } + + template + auto constexpr rend(new_type const & obj) + -> std::enable_if_t, + typename new_type::const_reverse_iterator> + { + return rend(obj.m_value); + } + + template + auto constexpr crend(new_type const & obj) + -> std::enable_if_t, + typename new_type::const_reverse_iterator> + { + return crend(obj.m_value); + } + +} // namespace nt + +namespace std +{ + template + struct hash> + { + template + auto constexpr operator()(nt::new_type const & object, + std::enable_if_t> * = nullptr) const + -> std::size_t + { + return std::hash{}(object.decay()); + } + }; +} // namespace std + +#endif diff --git a/source/lib/include/newtype/version.hpp b/source/lib/include/newtype/version.hpp new file mode 100644 index 0000000..8678514 --- /dev/null +++ b/source/lib/include/newtype/version.hpp @@ -0,0 +1,23 @@ +#ifndef NEWTYPE_VERSION_HPP +#define NEWTYPE_VERSION_HPP + +namespace nt +{ + + constexpr struct + { + int const major; + int const minor; + int const patch; + + char const * const name; + } version{ + .major = 1, + .minor = 1, + .patch = 0, + .name = "Anastasia", + }; + +} // namespace nt + +#endif \ No newline at end of file diff --git a/source/test/src/arithmetic.cpp b/source/test/src/arithmetic.cpp deleted file mode 100644 index 5048393..0000000 --- a/source/test/src/arithmetic.cpp +++ /dev/null @@ -1,300 +0,0 @@ -#include "newtype/derivable.hpp" -#include "newtype/deriving.hpp" -#include "newtype/impl/type_traits_extensions.hpp" -#include "newtype/newtype.hpp" - -#include - -#include - -SCENARIO("Addition", "[arithmetic]") -{ - struct addable_type - { - auto constexpr operator+(addable_type const &) const -> addable_type - { - return {}; - }; - }; - - GIVEN("A new_type instance not deriving nt::Arithmetic") - { - using type_alias = nt::new_type; - - THEN("it is not addable") - { - REQUIRE(!nt::impl::is_addable_v); - } - } - - GIVEN("A new_type deriving nt::Arithmetic") - { - using type_alias = nt::new_type; - - THEN("it is addable") - { - REQUIRE(nt::impl::is_addable_v); - } - } - - GIVEN("A new_type over a non-addable class type deriving nt::Arithmetic") - { - using type_alias = nt::new_type; - - THEN("it is not addable") - { - REQUIRE(!nt::impl::is_addable_v == nt::impl::is_addable_v); - } - } - - GIVEN("A new_type over an addable class type deriving nt::Arithmetic") - { - using type_alias = nt::new_type; - - THEN("it is addable") - { - REQUIRE(nt::impl::is_addable_v == nt::impl::is_addable_v); - } - } - - GIVEN("A new_type deriving nt::Arithmetic") - { - using type_alias = nt::new_type; - - THEN("addition produces the same type") - { - REQUIRE(std::is_same_v() + std::declval())>); - } - } - - GIVEN("Two objects of a new_type deriving nt::Arithmetic") - { - using type_alias = nt::new_type; - auto lhs = type_alias{24}; - auto rhs = type_alias{18}; - - THEN("addition produces the correct result with respect to the base type") - { - REQUIRE((lhs + rhs).decay() == 24 + 18); - } - } -} - -SCENARIO("Subtraction", "[arithmetic]") -{ - struct subtractable_type - { - auto constexpr operator-(subtractable_type const &) const -> subtractable_type - { - return {}; - }; - }; - - GIVEN("A new_type not deriving nt::arithmetic") - { - using type_alias = nt::new_type; - - THEN("it is not subtractable") - { - REQUIRE(!nt::impl::is_subtractable_v); - } - } - - GIVEN("A new_type deriving nt::Arithmetic") - { - using type_alias = nt::new_type; - - THEN("it is subtractable") - { - REQUIRE(nt::impl::is_subtractable_v); - } - } - - GIVEN("A new_type over a non-subtractable class type deriving nt::Arithmetic") - { - using type_alias = nt::new_type; - - THEN("it is not addable") - { - REQUIRE(!nt::impl::is_subtractable_v); - } - } - - GIVEN("A new_type over a subtractable class type deriving nt::Arithmetic") - { - using type_alias = nt::new_type; - - THEN("it is subtractable") - { - REQUIRE(nt::impl::is_subtractable_v); - } - } - - GIVEN("A new_type deriving nt::Arithmetic") - { - using type_alias = nt::new_type; - - THEN("subtraction produces the same type") - { - REQUIRE(std::is_same_v() - std::declval())>); - } - } - - GIVEN("Two objects of a new_type deriving nt::Arithmetic") - { - using type_alias = nt::new_type; - auto lhs = type_alias{24}; - auto rhs = type_alias{18}; - - THEN("subtraction produces the correct result with respect to the base type") - { - REQUIRE((lhs - rhs).decay() == 24 - 18); - } - } -} - -SCENARIO("Multiplication", "[arithmetic]") -{ - struct multipliable_type - { - auto constexpr operator*(multipliable_type const &) const -> multipliable_type - { - return {}; - }; - }; - - GIVEN("A new_type not deriving nt::arithmetic") - { - using type_alias = nt::new_type; - - THEN("it is not multipliable") - { - REQUIRE(!nt::impl::is_multipliable_v); - } - } - - GIVEN("A new_type deriving nt::Arithmetic") - { - using type_alias = nt::new_type; - - THEN("it is multipliable") - { - REQUIRE(nt::impl::is_multipliable_v); - } - } - - GIVEN("A new_type over a non-multipliable class type deriving nt::Arithmetic") - { - using type_alias = nt::new_type; - - THEN("it is not multipliable") - { - REQUIRE(!nt::impl::is_multipliable_v); - } - } - - GIVEN("A new_type over a multipliable class type deriving nt::Arithmetic") - { - using type_alias = nt::new_type; - - THEN("it is multipliable") - { - REQUIRE(nt::impl::is_multipliable_v); - } - } - - GIVEN("A new_type deriving nt::Arithmetic") - { - using type_alias = nt::new_type; - - THEN("multiplication produces the same type") - { - REQUIRE(std::is_same_v() * std::declval())>); - } - } - - GIVEN("Two objects of a new_type deriving nt::Arithmetic") - { - using type_alias = nt::new_type; - auto lhs = type_alias{24}; - auto rhs = type_alias{18}; - - THEN("multiplication produces the correct result with respect to the base type") - { - REQUIRE((lhs * rhs).decay() == 24 * 18); - } - } -} - -SCENARIO("Division", "[arithmetic]") -{ - struct dividable_type - { - auto constexpr operator/(dividable_type const &) const -> dividable_type - { - return {}; - }; - }; - - GIVEN("A new_type not deriving nt::arithmetic") - { - using type_alias = nt::new_type; - - THEN("it is not divisible") - { - REQUIRE(!nt::impl::is_dividable_v); - } - } - - GIVEN("A new_type deriving nt::Arithmetic") - { - using type_alias = nt::new_type; - - THEN("it is divisible") - { - REQUIRE(nt::impl::is_dividable_v); - } - } - - GIVEN("A new_type over a non-divisible class type deriving nt::Arithmetic") - { - using type_alias = nt::new_type; - - THEN("it is not divisible") - { - REQUIRE(!nt::impl::is_dividable_v); - } - } - - GIVEN("A new_type over a divisible class type deriving nt::Arithmetic") - { - using type_alias = nt::new_type; - - THEN("it is divisible") - { - REQUIRE(nt::impl::is_dividable_v); - } - } - - GIVEN("A new_type deriving nt::Arithmetic") - { - using type_alias = nt::new_type; - - THEN("division produces the same type") - { - REQUIRE(std::is_same_v() / std::declval())>); - } - } - - GIVEN("Two objects of a new_type deriving nt::Arithmetic") - { - using type_alias = nt::new_type; - auto lhs = type_alias{30}; - auto rhs = type_alias{15}; - - THEN("division produces the correct result with respect to the base type") - { - REQUIRE((lhs / rhs).decay() == 30 / 15); - } - } -} diff --git a/source/test/src/conversion_suite.cpp b/source/test/src/conversion_suite.cpp deleted file mode 100644 index cbe2463..0000000 --- a/source/test/src/conversion_suite.cpp +++ /dev/null @@ -1,201 +0,0 @@ -#include "conversion_suite.hpp" - -#include "kawaii.hpp" -#include "newtype/derivable.hpp" -#include "newtype/deriving.hpp" -#include "newtype/newtype.hpp" - -#include - -#include -#include -#include -#include -#include -#include -#include - -inline namespace traits_extensions -{ - - template - struct is_implicitly_convertible : std::false_type - { - }; - - template - struct is_implicitly_convertible() = std::declval())>> : std::true_type - { - }; - - template - auto constexpr is_implicitly_convertible_v = is_implicitly_convertible::value; - -} // namespace traits_extensions - -inline namespace ddt_support -{ - - template - struct datum - { - T value; - cute::test_failure failure; - }; - - template - auto generate_test_set(std::size_t size) -> std::vector> - { - auto device = std::random_device{}; - auto generator = std::mt19937{device()}; - auto distribution = [&] { - auto min = std::numeric_limits::min(); - auto max = std::numeric_limits::max(); - if constexpr (std::is_floating_point_v) - { - return std::uniform_real_distribution(min, max); - } - else - { - return std::uniform_int_distribution(min, max); - } - }(); - - auto data = std::vector>{}; - generate_n(std::back_inserter(data), size, [&] { - auto point = distribution(generator); - return datum{point, DDT()}; - }); - return data; - } - -} // namespace ddt_support - -inline namespace implicit_conversion_tests -{ - - template - auto a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type() -> void - { - using type_alias = nt::new_type; - ASSERT(!(is_implicitly_convertible_v)); - } - - template - auto a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type() -> void - { - using type_alias = nt::new_type; - ASSERT((is_implicitly_convertible_v)); - } - -} // namespace implicit_conversion_tests - -inline namespace decay_tests -{ - - template - auto decay_on_a_new__type_has_a_return_type_equal_to_the_base_type() -> void - { - using type_alias = nt::new_type; - ASSERT((std::is_same_v().decay())>)); - } - - template - auto decay_on_a_new__type_returns_the_underlying_value() -> void - { - using type_alias = nt::new_type; - auto data = generate_test_set(2 << 16); - for_each(begin(data), end(data), [](auto & test) { ASSERT_EQUAL_DDT(test.value, type_alias{test.value}.decay(), test.failure); }); - } - -} // namespace decay_tests - -inline namespace decay_noexcept_tests -{ - - auto decay_on_a_new__type_is_noexcept_if_the_base_type_can_be_copied_without_throwing() -> void - { - static_assert(std::is_nothrow_copy_constructible_v, "Sanity check"); - using type_alias = nt::new_type; - ASSERT(noexcept(type_alias{}.decay())); - } - - auto decay_on_a_new__type_is_not_noexcept_if_the_base_type_can_be_not_copied_without_throwing() -> void - { - struct strange_type - { - strange_type() = default; - strange_type(strange_type const &) noexcept(false) - { - } - }; - - static_assert(!std::is_nothrow_copy_constructible_v, "Sanity check"); - using type_alias = nt::new_type; - ASSERT(!noexcept(type_alias{}.decay())); - } - -} // namespace decay_noexcept_tests - -inline namespace conversion_operator_noexcept_tests -{ - - auto new__type_conversion_operator_is_noexcept_if_the_base_type_can_be_copied_without_throwing() -> void - { - static_assert(std::is_nothrow_copy_constructible_v, "Sanity check"); - using type_alias = nt::new_type; - ASSERT(noexcept(static_cast(type_alias{}))); - } - - auto new__type_conversion_operator_is_not_noexcept_if_the_base_type_can_not_be_copied_without_throwing() -> void - { - struct strange_type - { - strange_type() = default; - strange_type(strange_type const &) noexcept(false) - { - } - }; - - static_assert(!std::is_nothrow_copy_constructible_v, "Sanity check"); - using type_alias = nt::new_type; - ASSERT(!noexcept(static_cast(type_alias{}))); - } - -} // namespace conversion_operator_noexcept_tests - -auto conversion_suite() -> std::pair -{ - return {{ - /// Implicit Conversion Tests - KAWAII(a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type), - KAWAII(a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type), - KAWAII(a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type), - KAWAII(a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type), - KAWAII(a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type), - KAWAII(a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type), - KAWAII(a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type), - KAWAII(a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type), - KAWAII(a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type), - KAWAII(a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type), - - /// Decay Tests - KAWAII(decay_on_a_new__type_has_a_return_type_equal_to_the_base_type), - KAWAII(decay_on_a_new__type_has_a_return_type_equal_to_the_base_type), - KAWAII(decay_on_a_new__type_has_a_return_type_equal_to_the_base_type), - KAWAII(decay_on_a_new__type_has_a_return_type_equal_to_the_base_type), - KAWAII(decay_on_a_new__type_has_a_return_type_equal_to_the_base_type), - KAWAII(decay_on_a_new__type_returns_the_underlying_value), - KAWAII(decay_on_a_new__type_returns_the_underlying_value), - KAWAII(decay_on_a_new__type_returns_the_underlying_value), - - /// Decay noexcept Tests - KAWAII(decay_on_a_new__type_is_noexcept_if_the_base_type_can_be_copied_without_throwing), - KAWAII(decay_on_a_new__type_is_not_noexcept_if_the_base_type_can_be_not_copied_without_throwing), - - /// Conversion Operator noexcept Tests - KAWAII(new__type_conversion_operator_is_noexcept_if_the_base_type_can_be_copied_without_throwing), - KAWAII(new__type_conversion_operator_is_not_noexcept_if_the_base_type_can_not_be_copied_without_throwing), - }, - "Conversion Tests"}; -} \ No newline at end of file diff --git a/source/test/src/derivation_clause_suite.cpp b/source/test/src/derivation_clause_suite.cpp deleted file mode 100644 index 86a34ab..0000000 --- a/source/test/src/derivation_clause_suite.cpp +++ /dev/null @@ -1,312 +0,0 @@ -#include "derivation_clause_suite.hpp" - -#include "kawaii.hpp" -#include "newtype/derivable.hpp" -#include "newtype/deriving.hpp" - -#include - -#include - -inline namespace subset_tests -{ - - auto an_empty_derivation_clause_does_not_contain_any_derivable() -> void - { - auto derivation_clause = nt::deriving(); - ASSERT(!derivation_clause(nt::Show)); - } - - auto a_derivation_clause_containing_only_show_does_not_contain_eqbase() -> void - { - auto derivation_clause = deriving(nt::Show); - ASSERT(!derivation_clause(nt::EqBase)); - } - - auto a_derivation_clause_containing_only_show_does_contain_show() -> void - { - auto derivation_clause = deriving(nt::Show); - ASSERT(derivation_clause(nt::Show)); - } - - auto a_derivation_clause_containing_only_show_and_eqbase_does_contain_show() -> void - { - auto derivation_clause = deriving(nt::Show, nt::EqBase); - ASSERT(derivation_clause(nt::Show)); - } - - auto a_derivation_clause_containing_only_show_and_eqbase_does_contain_both_show_and_eqbase() -> void - { - auto derivation_clause = deriving(nt::Show, nt::EqBase); - ASSERT(derivation_clause(nt::Show, nt::EqBase)); - } - - auto a_derivation_clause_containing_only_show_and_eqbase_does_not_contain_arithmetic() -> void - { - auto derivation_clause = deriving(nt::Show, nt::EqBase); - ASSERT(!derivation_clause(nt::Arithmetic)); - } - - auto a_derivation_clause_containing_only_show_and_eqbase_does_not_contain_both_show_and_arithmetic() -> void - { - auto derivation_clause = deriving(nt::Show, nt::EqBase); - ASSERT(!derivation_clause(nt::Show, nt::Arithmetic)); - } - -} // namespace subset_tests - -inline namespace less_than_tests -{ - - auto a_derivation_clause_containing_only_show_compares_less_than_one_containing_show_and_eqbase() -> void - { - auto only_show = deriving(nt::Show); - auto show_and_eqbase = deriving(nt::Show, nt::EqBase); - - ASSERT(only_show < show_and_eqbase); - } - - auto a_derivation_clause_containing_only_show_and_eqbase_does_not_compare_less_than_one_containing_show_and_eqbase() -> void - { - auto show_and_eqbase = deriving(nt::Show, nt::EqBase); - auto also_show_and_eqbase = deriving(nt::Show, nt::EqBase); - - ASSERT(!(show_and_eqbase < also_show_and_eqbase)); - } - - auto a_derivation_clause_containing_only_show_and_eqbase_does_not_compare_less_than_one_containing_eqbase_and_show() -> void - { - auto show_and_eqbase = deriving(nt::Show, nt::EqBase); - auto eqbase_and_show = deriving(nt::EqBase, nt::Show); - - ASSERT(!(show_and_eqbase < eqbase_and_show)); - } - - auto a_derivation_clause_containing_only_show_does_not_compare_less_than_one_containing_only_eqbase() -> void - { - auto show = deriving(nt::Show); - auto eqbase = deriving(nt::EqBase); - - ASSERT(!(show < eqbase)); - } - -} // namespace less_than_tests - -inline namespace greater_than_tests -{ - - auto a_derivation_clause_containing_only_show_and_eqbase_compares_greater_than_one_containing_only_show() -> void - { - auto show_and_eqbase = deriving(nt::Show, nt::EqBase); - auto show = deriving(nt::Show); - - ASSERT(show_and_eqbase > show); - } - - auto a_derivation_clause_containing_only_show_and_eqbase_does_not_compare_greater_than_one_containing_only_show_and_eqbase() -> void - { - auto show_and_eqbase = deriving(nt::Show, nt::EqBase); - auto also_show_and_eqbase = deriving(nt::Show, nt::EqBase); - - ASSERT(!(show_and_eqbase > also_show_and_eqbase)); - } - - auto a_derivation_clause_containing_only_show_and_eqbase_does_not_compare_greater_than_one_containing_only_eqbase_and_show() -> void - { - auto show_and_eqbase = deriving(nt::Show, nt::EqBase); - auto eqbase_and_show = deriving(nt::EqBase, nt::Show); - - ASSERT(!(show_and_eqbase > eqbase_and_show)); - } - - auto a_derivation_clause_containing_only_show_does_not_compare_greater_than_one_containing_only_eqbase() -> void - { - auto show = deriving(nt::Show); - auto eqbase = deriving(nt::EqBase); - - ASSERT(!(show > eqbase)); - } - -} // namespace greater_than_tests - -inline namespace eqbaseuals_tests -{ - - auto a_derivation_clause_containing_only_show_and_eqbase_is_eqbaseual_to_one_containing_only_show_and_eqbase() -> void - { - auto show_and_eqbase = deriving(nt::Show, nt::EqBase); - auto also_show_and_eqbase = deriving(nt::Show, nt::EqBase); - - ASSERT_EQUAL(show_and_eqbase, also_show_and_eqbase); - } - - auto a_derivation_clause_containing_only_show_and_eqbase_is_eqbaseual_to_one_containing_only_eqbase_and_show() -> void - { - auto show_and_eqbase = deriving(nt::Show, nt::EqBase); - auto eqbase_and_show = deriving(nt::EqBase, nt::Show); - - ASSERT_EQUAL(show_and_eqbase, eqbase_and_show); - } - - auto a_derivation_clause_containing_only_show_and_eqbase_is_not_eqbaseual_to_one_containing_only_arithmetic() -> void - { - auto show_and_eqbase = deriving(nt::Show, nt::EqBase); - auto arithmetic = deriving(nt::Arithmetic); - - ASSERT(!(show_and_eqbase == arithmetic)); - } - - auto a_derivation_clause_containing_only_show_is_not_eqbaseual_to_one_containing_only_arithmetic() -> void - { - auto show = deriving(nt::Show); - auto arithmetic = deriving(nt::Arithmetic); - - ASSERT(!(show == arithmetic)); - } - -} // namespace eqbaseuals_tests - -inline namespace not_eqbaseuals_tests -{ - - auto a_derivation_clause_containing_only_show_and_eqbase_is_not_not_eqbaseual_to_one_containing_only_show_and_eqbase() -> void - { - auto show_and_eqbase = deriving(nt::Show, nt::EqBase); - auto also_show_and_eqbase = deriving(nt::Show, nt::EqBase); - - ASSERT(!(show_and_eqbase != also_show_and_eqbase)); - } - - auto a_derivation_clause_containing_only_show_and_eqbase_is_not_not_eqbaseual_to_one_containing_only_eqbase_and_show() -> void - { - auto show_and_eqbase = deriving(nt::Show, nt::EqBase); - auto eqbase_and_show = deriving(nt::EqBase, nt::Show); - - ASSERT(!(show_and_eqbase != eqbase_and_show)); - } - - auto a_derivation_clause_containing_only_eqbase_and_show_is_not_eqbaseual_to_one_containing_only_arithmetic() -> void - { - auto eqbase_and_show = deriving(nt::EqBase, nt::Show); - auto arithmetic = deriving(nt::Arithmetic); - - ASSERT(eqbase_and_show != arithmetic); - } - - auto a_derivation_clause_containing_only_eqbase_is_not_eqbaseual_to_one_containing_only_arithmetic() -> void - { - auto eqbase = deriving(nt::EqBase); - auto arithmetic = deriving(nt::Arithmetic); - - ASSERT(eqbase != arithmetic); - } - -} // namespace not_eqbaseuals_tests - -inline namespace less_than_or_eqbaseual_tests -{ - - auto a_derivation_clause_containing_only_show_is_less_than_or_eqbaseual_to_one_containing_only_show_and_eqbase() -> void - { - auto only_show = deriving(nt::Show); - auto show_and_eqbase = deriving(nt::Show, nt::EqBase); - - ASSERT(only_show <= show_and_eqbase); - } - - auto a_derivation_clause_containing_only_show_and_eqbase_is_less_than_or_eqbaseual_to_one_containing_only_show_and_eqbase() -> void - { - auto show_and_eqbase = deriving(nt::Show, nt::EqBase); - auto also_show_and_eqbase = deriving(nt::Show, nt::EqBase); - - ASSERT(show_and_eqbase <= also_show_and_eqbase); - } - - auto a_derivation_clause_containing_only_arithmetic_is_neither_less_than_nor_eqbaseual_to_on_containing_only_show_and_eqbase() -> void - { - auto arithmetic = deriving(nt::Arithmetic); - auto show_and_eqbase = deriving(nt::Show, nt::EqBase); - - ASSERT(!(arithmetic <= show_and_eqbase)); - } - -} // namespace less_than_or_eqbaseual_tests - -inline namespace greater_than_or_eqbaseual_tests -{ - - auto a_derivation_clause_containing_only_show_and_eqbase_is_greater_than_or_eqbaseual_to_one_containing_only_show() -> void - { - auto only_show = deriving(nt::Show); - auto show_and_eqbase = deriving(nt::Show, nt::EqBase); - - ASSERT(show_and_eqbase >= only_show); - } - - auto a_derivation_clause_containing_only_show_and_eqbase_is_greater_than_or_eqbaseual_to_one_containing_only_show_and_eqbase() -> void - { - auto show_and_eqbase = deriving(nt::Show, nt::EqBase); - auto also_show_and_eqbase = deriving(nt::Show, nt::EqBase); - - ASSERT(show_and_eqbase >= also_show_and_eqbase); - } - - auto a_derivation_clause_containing_only_show_and_eqbase_is_neither_greater_than_nor_eqbaseual_to_on_containing_only_arithmetic() -> void - { - auto arithmetic = deriving(nt::Arithmetic); - auto show_and_eqbase = deriving(nt::Show, nt::EqBase); - - ASSERT(!(show_and_eqbase >= arithmetic)); - } - -} // namespace greater_than_or_eqbaseual_tests - -auto derivation_clause_suite() -> std::pair -{ - return { - { - /// Subset tests - KAWAII(an_empty_derivation_clause_does_not_contain_any_derivable), - KAWAII(a_derivation_clause_containing_only_show_does_not_contain_eqbase), - KAWAII(a_derivation_clause_containing_only_show_does_contain_show), - KAWAII(a_derivation_clause_containing_only_show_and_eqbase_does_contain_show), - KAWAII(a_derivation_clause_containing_only_show_and_eqbase_does_contain_both_show_and_eqbase), - KAWAII(a_derivation_clause_containing_only_show_and_eqbase_does_not_contain_arithmetic), - KAWAII(a_derivation_clause_containing_only_show_and_eqbase_does_not_contain_both_show_and_arithmetic), - - /// Less-than tests - KAWAII(a_derivation_clause_containing_only_show_compares_less_than_one_containing_show_and_eqbase), - KAWAII(a_derivation_clause_containing_only_show_and_eqbase_does_not_compare_less_than_one_containing_show_and_eqbase), - KAWAII(a_derivation_clause_containing_only_show_and_eqbase_does_not_compare_less_than_one_containing_eqbase_and_show), - KAWAII(a_derivation_clause_containing_only_show_does_not_compare_less_than_one_containing_only_eqbase), - - /// Greater-than tests - KAWAII(a_derivation_clause_containing_only_show_and_eqbase_compares_greater_than_one_containing_only_show), - KAWAII(a_derivation_clause_containing_only_show_and_eqbase_does_not_compare_greater_than_one_containing_only_show_and_eqbase), - KAWAII(a_derivation_clause_containing_only_show_and_eqbase_does_not_compare_greater_than_one_containing_only_eqbase_and_show), - KAWAII(a_derivation_clause_containing_only_show_does_not_compare_greater_than_one_containing_only_eqbase), - - /// Equals tests - KAWAII(a_derivation_clause_containing_only_show_and_eqbase_is_eqbaseual_to_one_containing_only_show_and_eqbase), - KAWAII(a_derivation_clause_containing_only_show_and_eqbase_is_eqbaseual_to_one_containing_only_eqbase_and_show), - KAWAII(a_derivation_clause_containing_only_show_and_eqbase_is_not_eqbaseual_to_one_containing_only_arithmetic), - KAWAII(a_derivation_clause_containing_only_show_is_not_eqbaseual_to_one_containing_only_arithmetic), - - /// Not-Equals tests - KAWAII(a_derivation_clause_containing_only_show_and_eqbase_is_not_not_eqbaseual_to_one_containing_only_show_and_eqbase), - KAWAII(a_derivation_clause_containing_only_show_and_eqbase_is_not_not_eqbaseual_to_one_containing_only_eqbase_and_show), - KAWAII(a_derivation_clause_containing_only_eqbase_and_show_is_not_eqbaseual_to_one_containing_only_arithmetic), - KAWAII(a_derivation_clause_containing_only_eqbase_is_not_eqbaseual_to_one_containing_only_arithmetic), - - /// Less-than or Equals tests - KAWAII(a_derivation_clause_containing_only_show_is_less_than_or_eqbaseual_to_one_containing_only_show_and_eqbase), - KAWAII(a_derivation_clause_containing_only_show_and_eqbase_is_less_than_or_eqbaseual_to_one_containing_only_show_and_eqbase), - KAWAII(a_derivation_clause_containing_only_arithmetic_is_neither_less_than_nor_eqbaseual_to_on_containing_only_show_and_eqbase), - - /// Greater-than or Equals tests - KAWAII(a_derivation_clause_containing_only_show_and_eqbase_is_greater_than_or_eqbaseual_to_one_containing_only_show), - KAWAII(a_derivation_clause_containing_only_show_and_eqbase_is_greater_than_or_eqbaseual_to_one_containing_only_show_and_eqbase), - KAWAII(a_derivation_clause_containing_only_show_and_eqbase_is_neither_greater_than_nor_eqbaseual_to_on_containing_only_arithmetic), - }, - "Derivation Clause Tests"}; -} \ No newline at end of file diff --git a/source/test/src/equality_comparison_suite.cpp b/source/test/src/equality_comparison_suite.cpp deleted file mode 100644 index 4e484f4..0000000 --- a/source/test/src/equality_comparison_suite.cpp +++ /dev/null @@ -1,188 +0,0 @@ -#include "equality_comparison_suite.hpp" - -#include "kawaii.hpp" -#include "newtype/derivable.hpp" -#include "newtype/deriving.hpp" -#include "newtype/newtype.hpp" - -#include - -#include -#include -#include - -inline namespace basic_equality_comparsion_tests -{ - - auto two_instances_of_the_same_new__type_with_the_same_value_compare_equal() -> void - { - using type_alias = nt::new_type; - - auto constexpr lhs = type_alias{42}; - auto constexpr rhs = type_alias{42}; - - ASSERT_EQUAL(lhs, rhs); - } - - auto two_instances_of_the_same_new__type_with_the_same_value_do_not_compare_not_equal() -> void - { - using type_alias = nt::new_type; - - auto constexpr lhs = type_alias{42}; - auto constexpr rhs = type_alias{42}; - - ASSERT(!(lhs != rhs)); - } - - auto two_instances_of_the_same_new__type_with_differing_values_do_compare_not_equal() -> void - { - using type_alias = nt::new_type; - - auto constexpr lhs = type_alias{42}; - auto constexpr rhs = type_alias{43}; - - ASSERT_NOT_EQUAL_TO(lhs, rhs); - } - - auto two_instances_of_the_same_new__type_with_differing_values_do_not_compare_equal() -> void - { - using type_alias = nt::new_type; - - auto constexpr lhs = type_alias{42}; - auto constexpr rhs = type_alias{43}; - - ASSERT(!(lhs == rhs)); - } - -} // namespace basic_equality_comparsion_tests - -inline namespace equality_comparsion_noexcept_tests -{ - - auto equality_comparison_on_a_new__type_is_noexcept_if_the_base_type_is_noexcept_comparable() -> void - { - using type_alias = nt::new_type; - static_assert(noexcept(std::declval() == std::declval()), "Sanity Check"); - ASSERT(noexcept(std::declval() == std::declval())); - } - - auto equality_comparison_on_a_new__type_is_not_noexcept_if_the_base_type_is_not_noexcept_comparable() -> void - { - struct strange_type - { - auto constexpr operator==(strange_type const &) const noexcept(false) -> bool - { - return false; - } - }; - - using type_alias = nt::new_type; - static_assert(!noexcept(std::declval() == std::declval()), "Sanity Check"); - ASSERT(!noexcept(std::declval() == std::declval())); - } - - auto inequality_comparison_on_a_new__type_is_noexcept_if_the_base_type_is_noexcept_comparable() -> void - { - using type_alias = nt::new_type; - static_assert(noexcept(std::declval() != std::declval()), "Sanity Check"); - ASSERT(noexcept(std::declval() != std::declval())); - } - - auto inequality_comparison_on_a_new__type_is_not_noexcept_if_the_base_type_is_not_noexcept_comparable() -> void - { - struct strange_type - { - auto constexpr operator!=(strange_type const &) const noexcept(false) -> bool - { - return false; - } - }; - - using type_alias = nt::new_type; - static_assert(!noexcept(std::declval() != std::declval()), "Sanity Check"); - ASSERT(!noexcept(std::declval() != std::declval())); - } - -} // namespace equality_comparsion_noexcept_tests - -inline namespace equality_comparison_return_type_tests -{ - - auto equality_comparsion_of_two_new__type_instances_returns_bool() -> void - { - using type_alias = nt::new_type; - ASSERT((std::is_same_v() == std::declval())>)); - } - - auto inequality_comparsion_of_two_new__type_instances_returns_bool() -> void - { - using type_alias = nt::new_type; - ASSERT((std::is_same_v() != std::declval())>)); - } - -} // namespace equality_comparison_return_type_tests - -inline namespace base_type_equality_comparison_tests -{ - - auto an_instance_of_a_new__type_compares_equal_to_an_instance_of_its_base_type_with_the_same_value() -> void - { - using type_alias = nt::new_type; - auto lhs = type_alias{42}; - auto rhs = 42; - ASSERT_EQUAL(lhs, rhs); - } - - auto an_instance_of_the_base_type_of_a_new__type_compares_equal_to_an_instance_of_the_new__type_with_the_same_value() -> void - { - using type_alias = nt::new_type; - auto lhs = 42; - auto rhs = type_alias{42}; - ASSERT_EQUAL(lhs, rhs); - } - - auto an_instance_of_a_new__type_compares_not_equal_to_an_instance_of_its_base_type_with_a_differing_value() -> void - { - using type_alias = nt::new_type; - auto lhs = type_alias{42}; - auto rhs = 43; - ASSERT(lhs != rhs); - } - - auto an_instance_of_the_base_type_of_a_new__type_compares_not_equal_to_an_instance_of_the_new__type_with_a_differing_value() -> void - { - using type_alias = nt::new_type; - auto lhs = 43; - auto rhs = type_alias{42}; - ASSERT(lhs != rhs); - } - -} // namespace base_type_equality_comparison_tests - -auto equality_comparison_suite() -> std::pair -{ - return {{ - // Basic Equality Comparison Tests - KAWAII(two_instances_of_the_same_new__type_with_the_same_value_compare_equal), - KAWAII(two_instances_of_the_same_new__type_with_the_same_value_do_not_compare_not_equal), - KAWAII(two_instances_of_the_same_new__type_with_differing_values_do_compare_not_equal), - KAWAII(two_instances_of_the_same_new__type_with_differing_values_do_not_compare_equal), - - // Equality Comparison noexcept Tests - KAWAII(equality_comparison_on_a_new__type_is_noexcept_if_the_base_type_is_noexcept_comparable), - KAWAII(equality_comparison_on_a_new__type_is_not_noexcept_if_the_base_type_is_not_noexcept_comparable), - KAWAII(inequality_comparison_on_a_new__type_is_noexcept_if_the_base_type_is_noexcept_comparable), - KAWAII(inequality_comparison_on_a_new__type_is_not_noexcept_if_the_base_type_is_not_noexcept_comparable), - - // Equality Comparison Return Type Tests - KAWAII(equality_comparsion_of_two_new__type_instances_returns_bool), - KAWAII(inequality_comparsion_of_two_new__type_instances_returns_bool), - - // Base-type Equality Comparison Tests - KAWAII(an_instance_of_a_new__type_compares_equal_to_an_instance_of_its_base_type_with_the_same_value), - KAWAII(an_instance_of_the_base_type_of_a_new__type_compares_equal_to_an_instance_of_the_new__type_with_the_same_value), - KAWAII(an_instance_of_a_new__type_compares_not_equal_to_an_instance_of_its_base_type_with_a_differing_value), - KAWAII(an_instance_of_the_base_type_of_a_new__type_compares_not_equal_to_an_instance_of_the_new__type_with_a_differing_value), - }, - "Equality Comparison Tests"}; -} \ No newline at end of file diff --git a/source/test/src/hash_suite.cpp b/source/test/src/hash_suite.cpp deleted file mode 100644 index b482414..0000000 --- a/source/test/src/hash_suite.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include "hash_suite.hpp" - -#include "kawaii.hpp" -#include "newtype/derivable.hpp" -#include "newtype/deriving.hpp" -#include "newtype/impl/type_traits_extensions.hpp" -#include "newtype/newtype.hpp" - -#include - -#include - -inline namespace hashable_tests -{ - - auto a_new__type_that_does_not_include_hash_in_its_derivation_clause_is_not_hashable() -> void - { - using type_alias = nt::new_type; - ASSERT(!nt::impl::is_hashable_v); - } - - auto a_new__type_that_does_include_hash_in_its_derivation_clause_is_hashable() -> void - { - static_assert(nt::impl::is_hashable_v, "Sanity Check"); - using type_alias = nt::new_type; - ASSERT(nt::impl::is_hashable_v); - } - - auto a_new__type_that_does_include_hash_in_its_derivation_clause_but_whose_base_type_is_not_hashable_is_also_not_hashable() -> void - { - struct not_hashable - { - }; - - static_assert(!nt::impl::is_hashable_v, "Sanity Check"); - using type_alias = nt::new_type; - ASSERT(!nt::impl::is_hashable_v); - } - -} // namespace hashable_tests - -inline namespace usage_tests -{ - - auto a_new__type_that_is_hashable_can_be_used_in_an_unordered__map() -> void - { - static_assert(nt::impl::is_hashable_v, "Sanity Check"); - using type_alias = nt::new_type; - - auto map = std::unordered_map{}; - map[type_alias{42}] = 43; - ASSERT_EQUAL(43, map[type_alias{42}]); - } - -} // namespace usage_tests - -auto hash_suite() -> std::pair -{ - return {{ - // Hashable Tests - KAWAII(a_new__type_that_does_not_include_hash_in_its_derivation_clause_is_not_hashable), - KAWAII(a_new__type_that_does_include_hash_in_its_derivation_clause_is_hashable), - KAWAII(a_new__type_that_does_include_hash_in_its_derivation_clause_but_whose_base_type_is_not_hashable_is_also_not_hashable), - - // Usage Tests - KAWAII(a_new__type_that_is_hashable_can_be_used_in_an_unordered__map), - }, - "std::hash Support Tests"}; -} \ No newline at end of file diff --git a/source/test/src/io_operators_suite.cpp b/source/test/src/io_operators_suite.cpp deleted file mode 100644 index 4e146a7..0000000 --- a/source/test/src/io_operators_suite.cpp +++ /dev/null @@ -1,121 +0,0 @@ -#include "io_operators_suite.hpp" - -#include "kawaii.hpp" -#include "newtype/derivable.hpp" -#include "newtype/deriving.hpp" -#include "newtype/newtype.hpp" - -#include - -#include -#include -#include -#include -#include - -inline namespace traits_extensions -{ - - template - struct has_stream_input : std::false_type - { - }; - - template - struct has_stream_input() >> std::declval())>> : std::true_type - { - }; - - template - auto constexpr has_stream_input_v = has_stream_input::value; - - template - struct has_stream_output : std::false_type - { - }; - - template - struct has_stream_output() << std::declval())>> : std::true_type - { - }; - - template - auto constexpr has_stream_output_v = has_stream_output::value; - -} // namespace traits_extensions - -inline namespace stream_input_operator_tests -{ - - auto a_new__type_has_the_stream_input_operator_if_the_derivation_clause_contains_read() -> void - { - using type_alias = nt::new_type; - ASSERT(has_stream_input_v); - } - - auto a_new__type_does_not_have_the_stream_input_operator_if_the_derivation_clause_does_not_contain_read() -> void - { - using type_alias = nt::new_type; - ASSERT(!has_stream_input_v); - } - - auto a_instance_of_a_new__type_can_be_read_from_an_istream_if_the_base_type_can_be_read_from_an_istream() -> void - { - static_assert(has_stream_input_v, "Sanity Check"); - using type_alias = nt::new_type; - - auto obj = type_alias{}; - auto input = std::istringstream{"42"}; - - input >> obj; - - ASSERT_EQUAL(42, obj.decay()); - } - -} // namespace stream_input_operator_tests - -inline namespace stream_output_operator_tests -{ - - auto a_new__type_has_the_stream_output_operator_if_the_derivation_clause_contains_show() -> void - { - using type_alias = nt::new_type; - ASSERT(has_stream_output_v); - } - - auto a_new__type_does_not_have_the_stream_output_operator_if_the_derivation_clause_does_not_contain_show() -> void - { - using type_alias = nt::new_type; - ASSERT(!has_stream_output_v); - } - - auto a_instance_of_a_new__type_can_be_written_to_an_ostream_if_the_base_type_can_be_written_to_an_ostream() -> void - { - static_assert(has_stream_output_v, "Sanity Check"); - using type_alias = nt::new_type; - - auto obj = type_alias{42}; - auto output = std::ostringstream{}; - - output << obj; - - ASSERT_EQUAL("42", output.str()); - } - -} // namespace stream_output_operator_tests - -auto io_operators_suite() -> std::pair -{ - return {{ - // Stream Input Operator Tests - KAWAII(a_new__type_has_the_stream_input_operator_if_the_derivation_clause_contains_read), - KAWAII(a_new__type_does_not_have_the_stream_input_operator_if_the_derivation_clause_does_not_contain_read), - KAWAII(a_instance_of_a_new__type_can_be_read_from_an_istream_if_the_base_type_can_be_read_from_an_istream), - - // Stream Ouput Operator Tests - KAWAII(a_new__type_has_the_stream_output_operator_if_the_derivation_clause_contains_show), - KAWAII(a_new__type_does_not_have_the_stream_output_operator_if_the_derivation_clause_does_not_contain_show), - KAWAII(a_instance_of_a_new__type_can_be_written_to_an_ostream_if_the_base_type_can_be_written_to_an_ostream), - }, - "I/O Operators Tests"}; -} \ No newline at end of file diff --git a/source/test/src/iterable_suite.cpp b/source/test/src/iterable_suite.cpp deleted file mode 100644 index add4696..0000000 --- a/source/test/src/iterable_suite.cpp +++ /dev/null @@ -1,719 +0,0 @@ -#include "iterable_suite.hpp" - -#include "kawaii.hpp" -#include "newtype/derivable.hpp" -#include "newtype/deriving.hpp" -#include "newtype/impl/type_traits_extensions.hpp" -#include "newtype/newtype.hpp" - -#include - -#include -#include -#include -#include - -namespace -{ - - struct with_member - { - using iterator = char *; - using const_iterator = char const *; - using reverse_iterator = std::reverse_iterator; - using const_reverse_iterator = std::reverse_iterator; - - auto begin() -> iterator; - auto begin() const -> const_iterator; - auto cbegin() const -> const_iterator; - auto rbegin() -> reverse_iterator; - auto rbegin() const -> const_reverse_iterator; - auto crbegin() const -> const_reverse_iterator; - - auto end() -> iterator; - auto end() const -> const_iterator; - auto cend() const -> const_iterator; - auto rend() -> reverse_iterator; - auto rend() const -> const_reverse_iterator; - auto crend() const -> const_reverse_iterator; - }; - - struct with_free - { - using iterator = char *; - using const_iterator = char const *; - using reverse_iterator = std::reverse_iterator; - using const_reverse_iterator = std::reverse_iterator; - }; - - auto begin(with_free &) -> with_free::iterator - { - return {}; - } - - auto begin(with_free const &) -> with_free::const_iterator - { - return {}; - } - - auto cbegin(with_free const &) -> with_free::const_iterator - { - return {}; - } - - auto rbegin(with_free &) -> with_free::reverse_iterator - { - return {}; - } - - auto rbegin(with_free const &) -> with_free::const_reverse_iterator - { - return {}; - } - - auto crbegin(with_free const &) -> with_free::const_reverse_iterator - { - return {}; - } - - auto end(with_free &) -> with_free::iterator - { - return {}; - } - - auto end(with_free const &) -> with_free::const_iterator - { - return {}; - } - - auto cend(with_free const &) -> with_free::const_iterator - { - return {}; - } - - auto rend(with_free &) -> with_free::reverse_iterator - { - return {}; - } - - auto rend(with_free const &) -> with_free::const_reverse_iterator - { - return {}; - } - - auto crend(with_free const &) -> with_free::const_reverse_iterator - { - return {}; - } - -} // namespace - -inline namespace combined_enablement_tests -{ - - auto a_new__type_not_deriving_iterable_has_no_begin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_begin_v)); - } - - auto a_new__type_not_deriving_iterable_has_no_constant_begin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_begin_v)); - } - - auto a_new__type_not_deriving_iterable_has_no_cbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_cbegin_v)); - } - - auto a_new__type_not_deriving_iterable_has_no_rbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_rbegin_v)); - } - - auto a_new__type_not_deriving_iterable_has_no_constant_rbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_rbegin_v)); - } - - auto a_new__type_not_deriving_iterable_has_no_crbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_crbegin_v)); - } - - auto a_new__type_not_deriving_iterable_has_no_end() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_end_v)); - } - - auto a_new__type_not_deriving_iterable_has_no_constant_end() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_end_v)); - } - - auto a_new__type_not_deriving_iterable_has_no_cend() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_cend_v)); - } - - auto a_new__type_not_deriving_iterable_has_no_rend() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_rend_v)); - } - - auto a_new__type_not_deriving_iterable_has_no_constant_rend() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_rend_v)); - } - - auto a_new__type_not_deriving_iterable_has_no_crend() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_crend_v)); - } - - auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_begin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_begin_v)); - } - - auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_constant_begin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_begin_v)); - } - - auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_cbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_cbegin_v)); - } - - auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_rbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_rbegin_v)); - } - - auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_constant_rbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_rbegin_v)); - } - - auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_crbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_crbegin_v)); - } - - auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_end() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_end_v)); - } - - auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_constant_end() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_end_v)); - } - - auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_cend() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_cend_v)); - } - - auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_rend() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_rend_v)); - } - - auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_constant_rend() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_rend_v)); - } - - auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_crend() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_crend_v)); - } - -} // namespace combined_enablement_tests - -inline namespace member_enablement_tests -{ - - auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_begin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_member_begin_v)); - } - - auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_constant_begin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_member_begin_v)); - } - - auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_cbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_member_cbegin_v)); - } - - auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_rbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_member_rbegin_v)); - } - - auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_constant_rbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_member_rbegin_v)); - } - - auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_crbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_member_crbegin_v)); - } - - auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_end() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_member_end_v)); - } - - auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_constant_end() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_member_end_v)); - } - - auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_cend() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_member_cend_v)); - } - - auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_rend() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_member_rend_v)); - } - - auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_constant_rend() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_member_rend_v)); - } - - auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_crend() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_member_crend_v)); - } - - auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_begin() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_member_begin_v); - } - - auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_constant_begin() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_member_begin_v); - } - - auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_cbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_member_cbegin_v); - } - - auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_rbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_member_rbegin_v); - } - - auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_constant_rbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_member_rbegin_v); - } - - auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_crbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_member_crbegin_v); - } - - auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_end() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_member_end_v); - } - - auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_constant_end() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_member_end_v); - } - - auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_cend() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_member_cend_v); - } - - auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_rend() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_member_rend_v); - } - - auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_constant_rend() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_member_rend_v); - } - - auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_crend() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_member_crend_v); - } - -} // namespace member_enablement_tests - -inline namespace free_enablement_tests -{ - auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_begin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_free_begin_v)); - } - - auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_constant_begin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_free_begin_v)); - } - - auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_cbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_free_cbegin_v)); - } - - auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_rbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_free_rbegin_v)); - } - - auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_constant_rbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_free_rbegin_v)); - } - - auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_crbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_free_crbegin_v)); - } - - auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_end() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_free_end_v)); - } - - auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_constant_end() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_free_end_v)); - } - - auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_cend() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_free_cend_v)); - } - - auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_rend() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_free_rend_v)); - } - - auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_constant_rend() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_free_rend_v)); - } - - auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_crend() -> void - { - using type_alias = nt::new_type; - ASSERT(!(nt::impl::has_free_crend_v)); - } - - auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_begin() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_free_begin_v); - } - - auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_constant_begin() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_free_begin_v); - } - - auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_cbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_free_cbegin_v); - } - - auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_rbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_free_rbegin_v); - } - - auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_constant_rbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_free_rbegin_v); - } - - auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_crbegin() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_free_crbegin_v); - } - - auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_end() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_free_end_v); - } - - auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_constant_end() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_free_end_v); - } - - auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_cend() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_free_cend_v); - } - - auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_rend() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_free_rend_v); - } - - auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_constant_rend() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_free_rend_v); - } - - auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_crend() -> void - { - using type_alias = nt::new_type; - ASSERT(nt::impl::has_free_crend_v); - } - -} // namespace free_enablement_tests - -inline namespace semantic_tests -{ - - auto a_non_const_object_of_iterable_new__type_can_be_used_in_value_range_for() -> void - { - using type_alias = nt::new_type, struct tag, deriving(nt::Iterable)>; - auto object = type_alias{{1, 2, 3}}; - for (auto e : object) - { - (void)e; - } - ASSERT(true); - } - - auto a_const_object_of_iterable_new__type_can_be_used_in_value_range_for() -> void - { - using type_alias = nt::new_type, struct tag, deriving(nt::Iterable)>; - auto const object = type_alias{{1, 2, 3}}; - for (auto e : object) - { - (void)e; - } - ASSERT(true); - } - - auto a_non_const_object_of_iterable_new__type_can_be_used_in_reference_range_for() -> void - { - using type_alias = nt::new_type, struct tag, deriving(nt::Iterable)>; - auto object = type_alias{{1, 2, 3}}; - for (auto & e : object) - { - (void)e; - } - ASSERT(true); - } - - auto a_const_object_of_iterable_new__type_can_be_used_in_const_reference_range_for() -> void - { - using type_alias = nt::new_type, struct tag, deriving(nt::Iterable)>; - auto const object = type_alias{{1, 2, 3}}; - for (auto const & e : object) - { - (void)e; - } - ASSERT(true); - } - - auto applying_accumulate_to_an_interable_new__type_yields_the_same_result_as_when_applied_to_the_base_type() -> void - { - using type_alias = nt::new_type, struct tag, deriving(nt::Iterable)>; - auto const nt_object = type_alias{{1, 2, 3}}; - auto const bt_object = type_alias::base_type{1, 2, 3}; - - auto nt_result = std::accumulate(std::cbegin(nt_object), std::cend(nt_object), 0); - auto bt_result = std::accumulate(std::cbegin(bt_object), std::cend(bt_object), 0); - - ASSERT_EQUAL(bt_result, nt_result); - } - - auto iterating_over_an_iterable_new__type_yields_the_elements_in_the_same_order_as_when_iterating_the_base_type() -> void - { - using std::cbegin, std::cend, std::equal; - using type_alias = nt::new_type, struct tag, deriving(nt::Iterable)>; - auto const nt_object = type_alias{{1, 2, 3}}; - auto const bt_object = type_alias::base_type{1, 2, 3}; - - ASSERT(equal(cbegin(nt_object), cend(nt_object), cbegin(bt_object), cend(bt_object))); - } - -} // namespace semantic_tests - -auto iterable_suite() -> std::pair -{ - return {{ - /// Combined Enablement Tests - KAWAII(a_new__type_not_deriving_iterable_has_no_begin), - KAWAII(a_new__type_not_deriving_iterable_has_no_constant_begin), - KAWAII(a_new__type_not_deriving_iterable_has_no_cbegin), - KAWAII(a_new__type_not_deriving_iterable_has_no_rbegin), - KAWAII(a_new__type_not_deriving_iterable_has_no_constant_rbegin), - KAWAII(a_new__type_not_deriving_iterable_has_no_crbegin), - KAWAII(a_new__type_not_deriving_iterable_has_no_end), - KAWAII(a_new__type_not_deriving_iterable_has_no_constant_end), - KAWAII(a_new__type_not_deriving_iterable_has_no_cend), - KAWAII(a_new__type_not_deriving_iterable_has_no_rend), - KAWAII(a_new__type_not_deriving_iterable_has_no_constant_rend), - KAWAII(a_new__type_not_deriving_iterable_has_no_crend), - KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_begin), - KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_constant_begin), - KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_cbegin), - KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_rbegin), - KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_constant_rbegin), - KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_crbegin), - KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_end), - KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_constant_end), - KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_cend), - KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_rend), - KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_constant_rend), - KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_crend), - - /// Member Enablement Tests - KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_begin), - KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_constant_begin), - KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_cbegin), - KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_rbegin), - KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_constant_rbegin), - KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_crbegin), - KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_end), - KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_constant_end), - KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_cend), - KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_rend), - KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_constant_rend), - KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_crend), - KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_begin), - KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_constant_begin), - KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_cbegin), - KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_rbegin), - KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_constant_rbegin), - KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_crbegin), - KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_end), - KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_constant_end), - KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_cend), - KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_rend), - KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_constant_rend), - KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_crend), - - /// Free Enablement Tests - KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_begin), - KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_constant_begin), - KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_cbegin), - KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_rbegin), - KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_constant_rbegin), - KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_crbegin), - KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_end), - KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_constant_end), - KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_cend), - KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_rend), - KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_constant_rend), - KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_crend), - KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_begin), - KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_constant_begin), - KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_cbegin), - KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_rbegin), - KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_constant_rbegin), - KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_crbegin), - KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_end), - KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_constant_end), - KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_cend), - KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_rend), - KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_constant_rend), - KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_crend), - - /// Semantic Tests - KAWAII(a_non_const_object_of_iterable_new__type_can_be_used_in_value_range_for), - KAWAII(a_const_object_of_iterable_new__type_can_be_used_in_value_range_for), - KAWAII(a_non_const_object_of_iterable_new__type_can_be_used_in_reference_range_for), - KAWAII(a_const_object_of_iterable_new__type_can_be_used_in_const_reference_range_for), - KAWAII(applying_accumulate_to_an_interable_new__type_yields_the_same_result_as_when_applied_to_the_base_type), - KAWAII(iterating_over_an_iterable_new__type_yields_the_elements_in_the_same_order_as_when_iterating_the_base_type), - }, - - "Iterable Tests"}; -} \ No newline at end of file diff --git a/source/test/src/new_type_constructor_suite.cpp b/source/test/src/new_type_constructor_suite.cpp deleted file mode 100644 index fc3e9f6..0000000 --- a/source/test/src/new_type_constructor_suite.cpp +++ /dev/null @@ -1,91 +0,0 @@ -#include "new_type_constructor_suite.hpp" - -#include "kawaii.hpp" -#include "newtype/derivable.hpp" -#include "newtype/newtype.hpp" - -#include - -#include - -inline namespace constructor_tests -{ - - struct not_default_constructible - { - not_default_constructible() = delete; - }; - - auto a_new__type_based_on_a_type_that_is_default_constructible_is_default_constructible_too() -> void - { - using nt_float = nt::new_type; - - ASSERT(std::is_default_constructible_v); - } - - auto a_new__type_based_on_a_type_that_is_not_default_constructible_is_not_default_constructible_too() -> void - { - using nt_not_default_constructible = nt::new_type; - - ASSERT(!std::is_default_constructible_v); - } - - template - auto a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type() -> void - { - using nt_old = nt::new_type; - - ASSERT((std::is_constructible_v)); - } - - auto a_new__type_instance_can_be_copy_constructed_if_the_base_type_can_be_copy_constructed() -> void - { - using type_alias = nt::new_type; - ASSERT((std::is_copy_constructible_v)); - } - - auto a_new__type_instance_can_not_be_copy_constructed_if_the_base_type_can_not_be_copy_constructed() -> void - { - struct not_copy_constructible - { - not_copy_constructible() = default; - not_copy_constructible(not_copy_constructible const &) = delete; - not_copy_constructible(not_copy_constructible &&) = default; - auto operator=(not_copy_constructible const &) -> not_copy_constructible & = default; - auto operator=(not_copy_constructible &&) -> not_copy_constructible & = default; - }; - - using type_alias = nt::new_type; - ASSERT(!(std::is_copy_constructible_v)); - } - -} // namespace constructor_tests - -auto new_type_constructor_suite() -> std::pair -{ - return {{ - KAWAII(a_new__type_based_on_a_type_that_is_default_constructible_is_default_constructible_too), - KAWAII(a_new__type_based_on_a_type_that_is_not_default_constructible_is_not_default_constructible_too), - KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), - KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), - KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), - KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), - KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), - KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), - KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), - KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), - KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), - KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), - KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), - KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), - KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), - KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), - KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), - KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), - KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), - KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), - KAWAII(a_new__type_instance_can_be_copy_constructed_if_the_base_type_can_be_copy_constructed), - KAWAII(a_new__type_instance_can_not_be_copy_constructed_if_the_base_type_can_not_be_copy_constructed), - }, - "new_type Constructor Tests"}; -} \ No newline at end of file diff --git a/source/test/src/relational_operators_suite.cpp b/source/test/src/relational_operators_suite.cpp deleted file mode 100644 index 64fcba0..0000000 --- a/source/test/src/relational_operators_suite.cpp +++ /dev/null @@ -1,321 +0,0 @@ -#include "relational_operators_suite.hpp" - -#include "kawaii.hpp" -#include "newtype/derivable.hpp" -#include "newtype/deriving.hpp" -#include "newtype/newtype.hpp" - -#include - -#include -#include -#include - -inline namespace traits_extensions -{ - - template - struct has_less_than : std::false_type - { - }; - - template - struct has_less_than() < std::declval())>> : std::true_type - { - }; - - template - auto constexpr has_less_than_v = has_less_than::value; - - template - struct has_greater_than : std::false_type - { - }; - - template - struct has_greater_than() > std::declval())>> : std::true_type - { - }; - - template - auto constexpr has_greater_than_v = has_greater_than::value; - - template - struct has_less_than_equal_to : std::false_type - { - }; - - template - struct has_less_than_equal_to() <= std::declval())>> : std::true_type - { - }; - - template - auto constexpr has_less_than_equal_to_v = has_less_than_equal_to::value; - - template - struct has_greater_than_equal_to : std::false_type - { - }; - - template - struct has_greater_than_equal_to() >= std::declval())>> : std::true_type - { - }; - - template - auto constexpr has_greater_than_equal_to_v = has_greater_than_equal_to::value; - -} // namespace traits_extensions - -inline namespace relational_operator_presence_tests -{ - - auto an_instance_of_new__type_has_less_than_if_its_derivation_clause_contains_relational() -> void - { - using type_alias = nt::new_type; - ASSERT(has_less_than_v); - } - - auto an_instance_of_new__type_does_not_have_less_than_if_its_derivation_clause_does_not_contain_relational() -> void - { - using type_alias = nt::new_type; - ASSERT(!has_less_than_v); - } - - auto an_instance_of_new__type_has_greater_than_if_its_derivation_clause_contains_relational() -> void - { - using type_alias = nt::new_type; - ASSERT(has_greater_than_v); - } - - auto an_instance_of_new__type_does_not_have_greater_than_if_its_derivation_clause_does_not_contain_relational() -> void - { - using type_alias = nt::new_type; - ASSERT(!has_greater_than_v); - } - - auto an_instance_of_new__type_has_less_than_or_equal_to_if_its_derivation_clause_contains_relational() -> void - { - using type_alias = nt::new_type; - ASSERT(has_less_than_equal_to_v); - } - - auto an_instance_of_new__type_does_not_have_less_than_or_equal_to_if_its_derivation_clause_does_not_contain_relational() -> void - { - using type_alias = nt::new_type; - ASSERT(!has_less_than_equal_to_v); - } - - auto an_instance_of_new__type_has_greater_than_or_equal_to_if_its_derivation_clause_contains_relational() -> void - { - using type_alias = nt::new_type; - ASSERT(has_greater_than_equal_to_v); - } - - auto an_instance_of_new__type_does_not_have_greater_than_or_equal_to_if_its_derivation_clause_does_not_contain_relational() -> void - { - using type_alias = nt::new_type; - ASSERT(!has_greater_than_equal_to_v); - } - -} // namespace relational_operator_presence_tests - -inline namespace less_than_tests -{ - - auto two_instances_of_the_same_new__type_compare_less_than_if_both_contained_values_would_compare_less_than() -> void - { - using type_alias = nt::new_type; - auto constexpr lhs{21}; - auto constexpr rhs{42}; - static_assert(lhs < rhs, "Sanity Check"); - ASSERT_LESS(type_alias{lhs}, type_alias{rhs}); - } - - auto two_instances_of_the_same_new__type_do_not_compare_less_than_if_both_contained_values_would_not_compare_less_than() -> void - { - using type_alias = nt::new_type; - auto constexpr lhs{44}; - auto constexpr rhs{42}; - static_assert(!(lhs < rhs), "Sanity Check"); - ASSERT(!(type_alias{lhs} < type_alias{rhs})); - } - - auto two_instances_of_the_same_new__type_compare_less_than_or_equal_if_both_contained_values_would_compare_less_than_or_equal() -> void - { - using type_alias = nt::new_type; - auto constexpr lhs{33}; - auto constexpr rhs{42}; - static_assert(lhs <= rhs, "Sanity Check"); - ASSERT_LESS_EQUAL(type_alias{lhs}, type_alias{rhs}); - } - - auto two_instances_of_the_same_new__type_do_not_compare_less_than_or_equal_if_both_contained_values_would_not_compare_less_than_or_equal() - -> void - { - using type_alias = nt::new_type; - auto constexpr lhs{87}; - auto constexpr rhs{42}; - static_assert(!(lhs < rhs), "Sanity Check"); - ASSERT(!(type_alias{lhs} < type_alias{rhs})); - } - -} // namespace less_than_tests - -inline namespace greater_than_tests -{ - - auto two_instances_of_the_same_new__type_compare_greater_than_if_both_contained_values_would_compare_greater_than() -> void - { - using type_alias = nt::new_type; - auto constexpr lhs{42}; - auto constexpr rhs{21}; - static_assert(lhs > rhs, "Sanity Check"); - ASSERT_GREATER(type_alias{lhs}, type_alias{rhs}); - } - - auto two_instances_of_the_same_new__type_do_not_compare_greater_than_if_both_contained_values_would_not_compare_greater_than() -> void - { - using type_alias = nt::new_type; - auto constexpr lhs{42}; - auto constexpr rhs{44}; - static_assert(!(lhs > rhs), "Sanity Check"); - ASSERT(!(type_alias{lhs} > type_alias{rhs})); - } - - auto two_instances_of_the_same_new__type_compare_greater_than_or_equal_if_both_contained_values_would_compare_greater_than_or_equal() -> void - { - using type_alias = nt::new_type; - auto constexpr lhs{42}; - auto constexpr rhs{33}; - static_assert(lhs >= rhs, "Sanity Check"); - ASSERT_GREATER_EQUAL(type_alias{lhs}, type_alias{rhs}); - } - - auto - two_instances_of_the_same_new__type_do_not_compare_greater_than_or_equal_if_both_contained_values_would_not_compare_greater_than_or_equal() - -> void - { - using type_alias = nt::new_type; - auto constexpr lhs{42}; - auto constexpr rhs{87}; - static_assert(!(lhs > rhs), "Sanity Check"); - ASSERT(!(type_alias{lhs} > type_alias{rhs})); - } - -} // namespace greater_than_tests - -inline namespace relational_operator_noexcept_tests -{ - - struct strange_type - { - auto constexpr operator<(strange_type const & other) const noexcept(false) -> bool; - auto constexpr operator>(strange_type const & other) const noexcept(false) -> bool; - auto constexpr operator<=(strange_type const & other) const noexcept(false) -> bool; - auto constexpr operator>=(strange_type const & other) const noexcept(false) -> bool; - }; - - auto less_than_comparison_of_two_intances_of_the_same_new__type_is_noexcept_if_comparison_of_the_base_type_is_noexcept() -> void - { - using type_alias = nt::new_type; - static_assert(noexcept(std::declval() < std::declval()), "Sanity Check"); - ASSERT(noexcept(std::declval() < std::declval())); - } - - auto less_than_comparison_of_two_intances_of_the_same_new__type_is_not_noexcept_if_comparison_of_the_base_type_is_not_noexcept() -> void - { - using type_alias = nt::new_type; - static_assert(!noexcept(std::declval() < std::declval()), "Sanity Check"); - ASSERT(!noexcept(std::declval() < std::declval())); - } - - auto less_than_equal_to_comparison_of_two_intances_of_the_same_new__type_is_noexcept_if_comparison_of_the_base_type_is_noexcept() -> void - { - using type_alias = nt::new_type; - static_assert(noexcept(std::declval() <= std::declval()), "Sanity Check"); - ASSERT(noexcept(std::declval() <= std::declval())); - } - - auto less_than_equal_to_comparison_of_two_intances_of_the_same_new__type_is_not_noexcept_if_comparison_of_the_base_type_is_not_noexcept() - -> void - { - using type_alias = nt::new_type; - static_assert(!noexcept(std::declval() <= std::declval()), "Sanity Check"); - ASSERT(!noexcept(std::declval() <= std::declval())); - } - - auto greater_than_comparison_of_two_intances_of_the_same_new__type_is_noexcept_if_comparison_of_the_base_type_is_noexcept() -> void - { - using type_alias = nt::new_type; - static_assert(noexcept(std::declval() > std::declval()), "Sanity Check"); - ASSERT(noexcept(std::declval() > std::declval())); - } - - auto greater_than_comparison_of_two_intances_of_the_same_new__type_is_not_noexcept_if_comparison_of_the_base_type_is_not_noexcept() -> void - { - using type_alias = nt::new_type; - static_assert(!noexcept(std::declval() > std::declval()), "Sanity Check"); - ASSERT(!noexcept(std::declval() > std::declval())); - } - - auto greater_than_equal_to_comparison_of_two_intances_of_the_same_new__type_is_noexcept_if_comparison_of_the_base_type_is_noexcept() -> void - { - using type_alias = nt::new_type; - static_assert(noexcept(std::declval() >= std::declval()), "Sanity Check"); - ASSERT(noexcept(std::declval() >= std::declval())); - } - - auto greater_than_equal_to_comparison_of_two_intances_of_the_same_new__type_is_not_noexcept_if_comparison_of_the_base_type_is_not_noexcept() - -> void - { - using type_alias = nt::new_type; - static_assert(!noexcept(std::declval() >= std::declval()), "Sanity Check"); - ASSERT(!noexcept(std::declval() >= std::declval())); - } - -} // namespace relational_operator_noexcept_tests - -auto relational_operators_suite() -> std::pair -{ - return { - { - // clang-format off - - // Relational Operator Presensence Tests - KAWAII(an_instance_of_new__type_has_less_than_if_its_derivation_clause_contains_relational), - KAWAII(an_instance_of_new__type_does_not_have_less_than_if_its_derivation_clause_does_not_contain_relational), - KAWAII(an_instance_of_new__type_has_greater_than_if_its_derivation_clause_contains_relational), - KAWAII(an_instance_of_new__type_does_not_have_greater_than_if_its_derivation_clause_does_not_contain_relational), - KAWAII(an_instance_of_new__type_has_less_than_or_equal_to_if_its_derivation_clause_contains_relational), - KAWAII(an_instance_of_new__type_does_not_have_less_than_or_equal_to_if_its_derivation_clause_does_not_contain_relational), - KAWAII(an_instance_of_new__type_has_greater_than_or_equal_to_if_its_derivation_clause_contains_relational), - KAWAII(an_instance_of_new__type_does_not_have_greater_than_or_equal_to_if_its_derivation_clause_does_not_contain_relational), - - // Less-than Comparison Tests - KAWAII(two_instances_of_the_same_new__type_compare_less_than_if_both_contained_values_would_compare_less_than), - KAWAII(two_instances_of_the_same_new__type_do_not_compare_less_than_if_both_contained_values_would_not_compare_less_than), - KAWAII(two_instances_of_the_same_new__type_compare_less_than_or_equal_if_both_contained_values_would_compare_less_than_or_equal), - KAWAII(two_instances_of_the_same_new__type_do_not_compare_less_than_or_equal_if_both_contained_values_would_not_compare_less_than_or_equal), - - // Greater-than Comparison Tests - KAWAII(two_instances_of_the_same_new__type_compare_greater_than_if_both_contained_values_would_compare_greater_than), - KAWAII(two_instances_of_the_same_new__type_do_not_compare_greater_than_if_both_contained_values_would_not_compare_greater_than), - KAWAII(two_instances_of_the_same_new__type_compare_greater_than_or_equal_if_both_contained_values_would_compare_greater_than_or_equal), - KAWAII(two_instances_of_the_same_new__type_do_not_compare_greater_than_or_equal_if_both_contained_values_would_not_compare_greater_than_or_equal), - - // Relational Operators noexcept Tests - KAWAII(less_than_comparison_of_two_intances_of_the_same_new__type_is_noexcept_if_comparison_of_the_base_type_is_noexcept), - KAWAII(less_than_comparison_of_two_intances_of_the_same_new__type_is_not_noexcept_if_comparison_of_the_base_type_is_not_noexcept), - KAWAII(less_than_equal_to_comparison_of_two_intances_of_the_same_new__type_is_noexcept_if_comparison_of_the_base_type_is_noexcept), - KAWAII(less_than_equal_to_comparison_of_two_intances_of_the_same_new__type_is_not_noexcept_if_comparison_of_the_base_type_is_not_noexcept), - KAWAII(greater_than_comparison_of_two_intances_of_the_same_new__type_is_noexcept_if_comparison_of_the_base_type_is_noexcept), - KAWAII(greater_than_comparison_of_two_intances_of_the_same_new__type_is_not_noexcept_if_comparison_of_the_base_type_is_not_noexcept), - KAWAII(greater_than_equal_to_comparison_of_two_intances_of_the_same_new__type_is_noexcept_if_comparison_of_the_base_type_is_noexcept), - KAWAII(greater_than_equal_to_comparison_of_two_intances_of_the_same_new__type_is_not_noexcept_if_comparison_of_the_base_type_is_not_noexcept), - - // clang-format on - }, - "Relational Operators Tests"}; -} \ No newline at end of file diff --git a/source/tests/CMakeLists.txt b/source/tests/CMakeLists.txt new file mode 100644 index 0000000..fe405db --- /dev/null +++ b/source/tests/CMakeLists.txt @@ -0,0 +1,34 @@ +enable_testing() + +find_package("Catch2" "3.1" + COMPONENTS "Catch2WithMain" + REQUIRED +) + +include("Catch") + +add_executable("${PROJECT_NAME}_tests" + "src/arithmetic.cpp" + # "src/conversion_suite.cpp" + # "src/derivation_clause_suite.cpp" + # "src/equality_comparison_suite.cpp" + # "src/hash_suite.cpp" + # "src/io_operators_suite.cpp" + # "src/iterable_suite.cpp" + # "src/new_type_constructor_suite.cpp" + # "src/relational_operators_suite.cpp" +) + +target_link_libraries("${PROJECT_NAME}_tests" + "${PROJECT_NAME}::${PROJECT_NAME}" + "Catch2::Catch2WithMain" +) + +target_compile_options("${PROJECT_NAME}_tests" PRIVATE + "$<$:-Wall>" + "$<$:-Wextra>" + "$<$:-Werror>" + "$<$:-pedantic-errors>" +) + +catch_discover_tests("${PROJECT_NAME}_tests") diff --git a/source/tests/src/arithmetic.cpp b/source/tests/src/arithmetic.cpp new file mode 100644 index 0000000..5048393 --- /dev/null +++ b/source/tests/src/arithmetic.cpp @@ -0,0 +1,300 @@ +#include "newtype/derivable.hpp" +#include "newtype/deriving.hpp" +#include "newtype/impl/type_traits_extensions.hpp" +#include "newtype/newtype.hpp" + +#include + +#include + +SCENARIO("Addition", "[arithmetic]") +{ + struct addable_type + { + auto constexpr operator+(addable_type const &) const -> addable_type + { + return {}; + }; + }; + + GIVEN("A new_type instance not deriving nt::Arithmetic") + { + using type_alias = nt::new_type; + + THEN("it is not addable") + { + REQUIRE(!nt::impl::is_addable_v); + } + } + + GIVEN("A new_type deriving nt::Arithmetic") + { + using type_alias = nt::new_type; + + THEN("it is addable") + { + REQUIRE(nt::impl::is_addable_v); + } + } + + GIVEN("A new_type over a non-addable class type deriving nt::Arithmetic") + { + using type_alias = nt::new_type; + + THEN("it is not addable") + { + REQUIRE(!nt::impl::is_addable_v == nt::impl::is_addable_v); + } + } + + GIVEN("A new_type over an addable class type deriving nt::Arithmetic") + { + using type_alias = nt::new_type; + + THEN("it is addable") + { + REQUIRE(nt::impl::is_addable_v == nt::impl::is_addable_v); + } + } + + GIVEN("A new_type deriving nt::Arithmetic") + { + using type_alias = nt::new_type; + + THEN("addition produces the same type") + { + REQUIRE(std::is_same_v() + std::declval())>); + } + } + + GIVEN("Two objects of a new_type deriving nt::Arithmetic") + { + using type_alias = nt::new_type; + auto lhs = type_alias{24}; + auto rhs = type_alias{18}; + + THEN("addition produces the correct result with respect to the base type") + { + REQUIRE((lhs + rhs).decay() == 24 + 18); + } + } +} + +SCENARIO("Subtraction", "[arithmetic]") +{ + struct subtractable_type + { + auto constexpr operator-(subtractable_type const &) const -> subtractable_type + { + return {}; + }; + }; + + GIVEN("A new_type not deriving nt::arithmetic") + { + using type_alias = nt::new_type; + + THEN("it is not subtractable") + { + REQUIRE(!nt::impl::is_subtractable_v); + } + } + + GIVEN("A new_type deriving nt::Arithmetic") + { + using type_alias = nt::new_type; + + THEN("it is subtractable") + { + REQUIRE(nt::impl::is_subtractable_v); + } + } + + GIVEN("A new_type over a non-subtractable class type deriving nt::Arithmetic") + { + using type_alias = nt::new_type; + + THEN("it is not addable") + { + REQUIRE(!nt::impl::is_subtractable_v); + } + } + + GIVEN("A new_type over a subtractable class type deriving nt::Arithmetic") + { + using type_alias = nt::new_type; + + THEN("it is subtractable") + { + REQUIRE(nt::impl::is_subtractable_v); + } + } + + GIVEN("A new_type deriving nt::Arithmetic") + { + using type_alias = nt::new_type; + + THEN("subtraction produces the same type") + { + REQUIRE(std::is_same_v() - std::declval())>); + } + } + + GIVEN("Two objects of a new_type deriving nt::Arithmetic") + { + using type_alias = nt::new_type; + auto lhs = type_alias{24}; + auto rhs = type_alias{18}; + + THEN("subtraction produces the correct result with respect to the base type") + { + REQUIRE((lhs - rhs).decay() == 24 - 18); + } + } +} + +SCENARIO("Multiplication", "[arithmetic]") +{ + struct multipliable_type + { + auto constexpr operator*(multipliable_type const &) const -> multipliable_type + { + return {}; + }; + }; + + GIVEN("A new_type not deriving nt::arithmetic") + { + using type_alias = nt::new_type; + + THEN("it is not multipliable") + { + REQUIRE(!nt::impl::is_multipliable_v); + } + } + + GIVEN("A new_type deriving nt::Arithmetic") + { + using type_alias = nt::new_type; + + THEN("it is multipliable") + { + REQUIRE(nt::impl::is_multipliable_v); + } + } + + GIVEN("A new_type over a non-multipliable class type deriving nt::Arithmetic") + { + using type_alias = nt::new_type; + + THEN("it is not multipliable") + { + REQUIRE(!nt::impl::is_multipliable_v); + } + } + + GIVEN("A new_type over a multipliable class type deriving nt::Arithmetic") + { + using type_alias = nt::new_type; + + THEN("it is multipliable") + { + REQUIRE(nt::impl::is_multipliable_v); + } + } + + GIVEN("A new_type deriving nt::Arithmetic") + { + using type_alias = nt::new_type; + + THEN("multiplication produces the same type") + { + REQUIRE(std::is_same_v() * std::declval())>); + } + } + + GIVEN("Two objects of a new_type deriving nt::Arithmetic") + { + using type_alias = nt::new_type; + auto lhs = type_alias{24}; + auto rhs = type_alias{18}; + + THEN("multiplication produces the correct result with respect to the base type") + { + REQUIRE((lhs * rhs).decay() == 24 * 18); + } + } +} + +SCENARIO("Division", "[arithmetic]") +{ + struct dividable_type + { + auto constexpr operator/(dividable_type const &) const -> dividable_type + { + return {}; + }; + }; + + GIVEN("A new_type not deriving nt::arithmetic") + { + using type_alias = nt::new_type; + + THEN("it is not divisible") + { + REQUIRE(!nt::impl::is_dividable_v); + } + } + + GIVEN("A new_type deriving nt::Arithmetic") + { + using type_alias = nt::new_type; + + THEN("it is divisible") + { + REQUIRE(nt::impl::is_dividable_v); + } + } + + GIVEN("A new_type over a non-divisible class type deriving nt::Arithmetic") + { + using type_alias = nt::new_type; + + THEN("it is not divisible") + { + REQUIRE(!nt::impl::is_dividable_v); + } + } + + GIVEN("A new_type over a divisible class type deriving nt::Arithmetic") + { + using type_alias = nt::new_type; + + THEN("it is divisible") + { + REQUIRE(nt::impl::is_dividable_v); + } + } + + GIVEN("A new_type deriving nt::Arithmetic") + { + using type_alias = nt::new_type; + + THEN("division produces the same type") + { + REQUIRE(std::is_same_v() / std::declval())>); + } + } + + GIVEN("Two objects of a new_type deriving nt::Arithmetic") + { + using type_alias = nt::new_type; + auto lhs = type_alias{30}; + auto rhs = type_alias{15}; + + THEN("division produces the correct result with respect to the base type") + { + REQUIRE((lhs / rhs).decay() == 30 / 15); + } + } +} diff --git a/source/tests/src/conversion_suite.cpp b/source/tests/src/conversion_suite.cpp new file mode 100644 index 0000000..cbe2463 --- /dev/null +++ b/source/tests/src/conversion_suite.cpp @@ -0,0 +1,201 @@ +#include "conversion_suite.hpp" + +#include "kawaii.hpp" +#include "newtype/derivable.hpp" +#include "newtype/deriving.hpp" +#include "newtype/newtype.hpp" + +#include + +#include +#include +#include +#include +#include +#include +#include + +inline namespace traits_extensions +{ + + template + struct is_implicitly_convertible : std::false_type + { + }; + + template + struct is_implicitly_convertible() = std::declval())>> : std::true_type + { + }; + + template + auto constexpr is_implicitly_convertible_v = is_implicitly_convertible::value; + +} // namespace traits_extensions + +inline namespace ddt_support +{ + + template + struct datum + { + T value; + cute::test_failure failure; + }; + + template + auto generate_test_set(std::size_t size) -> std::vector> + { + auto device = std::random_device{}; + auto generator = std::mt19937{device()}; + auto distribution = [&] { + auto min = std::numeric_limits::min(); + auto max = std::numeric_limits::max(); + if constexpr (std::is_floating_point_v) + { + return std::uniform_real_distribution(min, max); + } + else + { + return std::uniform_int_distribution(min, max); + } + }(); + + auto data = std::vector>{}; + generate_n(std::back_inserter(data), size, [&] { + auto point = distribution(generator); + return datum{point, DDT()}; + }); + return data; + } + +} // namespace ddt_support + +inline namespace implicit_conversion_tests +{ + + template + auto a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type() -> void + { + using type_alias = nt::new_type; + ASSERT(!(is_implicitly_convertible_v)); + } + + template + auto a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type() -> void + { + using type_alias = nt::new_type; + ASSERT((is_implicitly_convertible_v)); + } + +} // namespace implicit_conversion_tests + +inline namespace decay_tests +{ + + template + auto decay_on_a_new__type_has_a_return_type_equal_to_the_base_type() -> void + { + using type_alias = nt::new_type; + ASSERT((std::is_same_v().decay())>)); + } + + template + auto decay_on_a_new__type_returns_the_underlying_value() -> void + { + using type_alias = nt::new_type; + auto data = generate_test_set(2 << 16); + for_each(begin(data), end(data), [](auto & test) { ASSERT_EQUAL_DDT(test.value, type_alias{test.value}.decay(), test.failure); }); + } + +} // namespace decay_tests + +inline namespace decay_noexcept_tests +{ + + auto decay_on_a_new__type_is_noexcept_if_the_base_type_can_be_copied_without_throwing() -> void + { + static_assert(std::is_nothrow_copy_constructible_v, "Sanity check"); + using type_alias = nt::new_type; + ASSERT(noexcept(type_alias{}.decay())); + } + + auto decay_on_a_new__type_is_not_noexcept_if_the_base_type_can_be_not_copied_without_throwing() -> void + { + struct strange_type + { + strange_type() = default; + strange_type(strange_type const &) noexcept(false) + { + } + }; + + static_assert(!std::is_nothrow_copy_constructible_v, "Sanity check"); + using type_alias = nt::new_type; + ASSERT(!noexcept(type_alias{}.decay())); + } + +} // namespace decay_noexcept_tests + +inline namespace conversion_operator_noexcept_tests +{ + + auto new__type_conversion_operator_is_noexcept_if_the_base_type_can_be_copied_without_throwing() -> void + { + static_assert(std::is_nothrow_copy_constructible_v, "Sanity check"); + using type_alias = nt::new_type; + ASSERT(noexcept(static_cast(type_alias{}))); + } + + auto new__type_conversion_operator_is_not_noexcept_if_the_base_type_can_not_be_copied_without_throwing() -> void + { + struct strange_type + { + strange_type() = default; + strange_type(strange_type const &) noexcept(false) + { + } + }; + + static_assert(!std::is_nothrow_copy_constructible_v, "Sanity check"); + using type_alias = nt::new_type; + ASSERT(!noexcept(static_cast(type_alias{}))); + } + +} // namespace conversion_operator_noexcept_tests + +auto conversion_suite() -> std::pair +{ + return {{ + /// Implicit Conversion Tests + KAWAII(a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type), + KAWAII(a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type), + KAWAII(a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type), + KAWAII(a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type), + KAWAII(a_new__type_without_deriving_implicit_conversion_is_not_implicitly_convertible_to_the_base_type), + KAWAII(a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type), + KAWAII(a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type), + KAWAII(a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type), + KAWAII(a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type), + KAWAII(a_new__type_with_deriving_implicit_conversion_is_implicitly_convertible_to_the_base_type), + + /// Decay Tests + KAWAII(decay_on_a_new__type_has_a_return_type_equal_to_the_base_type), + KAWAII(decay_on_a_new__type_has_a_return_type_equal_to_the_base_type), + KAWAII(decay_on_a_new__type_has_a_return_type_equal_to_the_base_type), + KAWAII(decay_on_a_new__type_has_a_return_type_equal_to_the_base_type), + KAWAII(decay_on_a_new__type_has_a_return_type_equal_to_the_base_type), + KAWAII(decay_on_a_new__type_returns_the_underlying_value), + KAWAII(decay_on_a_new__type_returns_the_underlying_value), + KAWAII(decay_on_a_new__type_returns_the_underlying_value), + + /// Decay noexcept Tests + KAWAII(decay_on_a_new__type_is_noexcept_if_the_base_type_can_be_copied_without_throwing), + KAWAII(decay_on_a_new__type_is_not_noexcept_if_the_base_type_can_be_not_copied_without_throwing), + + /// Conversion Operator noexcept Tests + KAWAII(new__type_conversion_operator_is_noexcept_if_the_base_type_can_be_copied_without_throwing), + KAWAII(new__type_conversion_operator_is_not_noexcept_if_the_base_type_can_not_be_copied_without_throwing), + }, + "Conversion Tests"}; +} \ No newline at end of file diff --git a/source/tests/src/derivation_clause_suite.cpp b/source/tests/src/derivation_clause_suite.cpp new file mode 100644 index 0000000..86a34ab --- /dev/null +++ b/source/tests/src/derivation_clause_suite.cpp @@ -0,0 +1,312 @@ +#include "derivation_clause_suite.hpp" + +#include "kawaii.hpp" +#include "newtype/derivable.hpp" +#include "newtype/deriving.hpp" + +#include + +#include + +inline namespace subset_tests +{ + + auto an_empty_derivation_clause_does_not_contain_any_derivable() -> void + { + auto derivation_clause = nt::deriving(); + ASSERT(!derivation_clause(nt::Show)); + } + + auto a_derivation_clause_containing_only_show_does_not_contain_eqbase() -> void + { + auto derivation_clause = deriving(nt::Show); + ASSERT(!derivation_clause(nt::EqBase)); + } + + auto a_derivation_clause_containing_only_show_does_contain_show() -> void + { + auto derivation_clause = deriving(nt::Show); + ASSERT(derivation_clause(nt::Show)); + } + + auto a_derivation_clause_containing_only_show_and_eqbase_does_contain_show() -> void + { + auto derivation_clause = deriving(nt::Show, nt::EqBase); + ASSERT(derivation_clause(nt::Show)); + } + + auto a_derivation_clause_containing_only_show_and_eqbase_does_contain_both_show_and_eqbase() -> void + { + auto derivation_clause = deriving(nt::Show, nt::EqBase); + ASSERT(derivation_clause(nt::Show, nt::EqBase)); + } + + auto a_derivation_clause_containing_only_show_and_eqbase_does_not_contain_arithmetic() -> void + { + auto derivation_clause = deriving(nt::Show, nt::EqBase); + ASSERT(!derivation_clause(nt::Arithmetic)); + } + + auto a_derivation_clause_containing_only_show_and_eqbase_does_not_contain_both_show_and_arithmetic() -> void + { + auto derivation_clause = deriving(nt::Show, nt::EqBase); + ASSERT(!derivation_clause(nt::Show, nt::Arithmetic)); + } + +} // namespace subset_tests + +inline namespace less_than_tests +{ + + auto a_derivation_clause_containing_only_show_compares_less_than_one_containing_show_and_eqbase() -> void + { + auto only_show = deriving(nt::Show); + auto show_and_eqbase = deriving(nt::Show, nt::EqBase); + + ASSERT(only_show < show_and_eqbase); + } + + auto a_derivation_clause_containing_only_show_and_eqbase_does_not_compare_less_than_one_containing_show_and_eqbase() -> void + { + auto show_and_eqbase = deriving(nt::Show, nt::EqBase); + auto also_show_and_eqbase = deriving(nt::Show, nt::EqBase); + + ASSERT(!(show_and_eqbase < also_show_and_eqbase)); + } + + auto a_derivation_clause_containing_only_show_and_eqbase_does_not_compare_less_than_one_containing_eqbase_and_show() -> void + { + auto show_and_eqbase = deriving(nt::Show, nt::EqBase); + auto eqbase_and_show = deriving(nt::EqBase, nt::Show); + + ASSERT(!(show_and_eqbase < eqbase_and_show)); + } + + auto a_derivation_clause_containing_only_show_does_not_compare_less_than_one_containing_only_eqbase() -> void + { + auto show = deriving(nt::Show); + auto eqbase = deriving(nt::EqBase); + + ASSERT(!(show < eqbase)); + } + +} // namespace less_than_tests + +inline namespace greater_than_tests +{ + + auto a_derivation_clause_containing_only_show_and_eqbase_compares_greater_than_one_containing_only_show() -> void + { + auto show_and_eqbase = deriving(nt::Show, nt::EqBase); + auto show = deriving(nt::Show); + + ASSERT(show_and_eqbase > show); + } + + auto a_derivation_clause_containing_only_show_and_eqbase_does_not_compare_greater_than_one_containing_only_show_and_eqbase() -> void + { + auto show_and_eqbase = deriving(nt::Show, nt::EqBase); + auto also_show_and_eqbase = deriving(nt::Show, nt::EqBase); + + ASSERT(!(show_and_eqbase > also_show_and_eqbase)); + } + + auto a_derivation_clause_containing_only_show_and_eqbase_does_not_compare_greater_than_one_containing_only_eqbase_and_show() -> void + { + auto show_and_eqbase = deriving(nt::Show, nt::EqBase); + auto eqbase_and_show = deriving(nt::EqBase, nt::Show); + + ASSERT(!(show_and_eqbase > eqbase_and_show)); + } + + auto a_derivation_clause_containing_only_show_does_not_compare_greater_than_one_containing_only_eqbase() -> void + { + auto show = deriving(nt::Show); + auto eqbase = deriving(nt::EqBase); + + ASSERT(!(show > eqbase)); + } + +} // namespace greater_than_tests + +inline namespace eqbaseuals_tests +{ + + auto a_derivation_clause_containing_only_show_and_eqbase_is_eqbaseual_to_one_containing_only_show_and_eqbase() -> void + { + auto show_and_eqbase = deriving(nt::Show, nt::EqBase); + auto also_show_and_eqbase = deriving(nt::Show, nt::EqBase); + + ASSERT_EQUAL(show_and_eqbase, also_show_and_eqbase); + } + + auto a_derivation_clause_containing_only_show_and_eqbase_is_eqbaseual_to_one_containing_only_eqbase_and_show() -> void + { + auto show_and_eqbase = deriving(nt::Show, nt::EqBase); + auto eqbase_and_show = deriving(nt::EqBase, nt::Show); + + ASSERT_EQUAL(show_and_eqbase, eqbase_and_show); + } + + auto a_derivation_clause_containing_only_show_and_eqbase_is_not_eqbaseual_to_one_containing_only_arithmetic() -> void + { + auto show_and_eqbase = deriving(nt::Show, nt::EqBase); + auto arithmetic = deriving(nt::Arithmetic); + + ASSERT(!(show_and_eqbase == arithmetic)); + } + + auto a_derivation_clause_containing_only_show_is_not_eqbaseual_to_one_containing_only_arithmetic() -> void + { + auto show = deriving(nt::Show); + auto arithmetic = deriving(nt::Arithmetic); + + ASSERT(!(show == arithmetic)); + } + +} // namespace eqbaseuals_tests + +inline namespace not_eqbaseuals_tests +{ + + auto a_derivation_clause_containing_only_show_and_eqbase_is_not_not_eqbaseual_to_one_containing_only_show_and_eqbase() -> void + { + auto show_and_eqbase = deriving(nt::Show, nt::EqBase); + auto also_show_and_eqbase = deriving(nt::Show, nt::EqBase); + + ASSERT(!(show_and_eqbase != also_show_and_eqbase)); + } + + auto a_derivation_clause_containing_only_show_and_eqbase_is_not_not_eqbaseual_to_one_containing_only_eqbase_and_show() -> void + { + auto show_and_eqbase = deriving(nt::Show, nt::EqBase); + auto eqbase_and_show = deriving(nt::EqBase, nt::Show); + + ASSERT(!(show_and_eqbase != eqbase_and_show)); + } + + auto a_derivation_clause_containing_only_eqbase_and_show_is_not_eqbaseual_to_one_containing_only_arithmetic() -> void + { + auto eqbase_and_show = deriving(nt::EqBase, nt::Show); + auto arithmetic = deriving(nt::Arithmetic); + + ASSERT(eqbase_and_show != arithmetic); + } + + auto a_derivation_clause_containing_only_eqbase_is_not_eqbaseual_to_one_containing_only_arithmetic() -> void + { + auto eqbase = deriving(nt::EqBase); + auto arithmetic = deriving(nt::Arithmetic); + + ASSERT(eqbase != arithmetic); + } + +} // namespace not_eqbaseuals_tests + +inline namespace less_than_or_eqbaseual_tests +{ + + auto a_derivation_clause_containing_only_show_is_less_than_or_eqbaseual_to_one_containing_only_show_and_eqbase() -> void + { + auto only_show = deriving(nt::Show); + auto show_and_eqbase = deriving(nt::Show, nt::EqBase); + + ASSERT(only_show <= show_and_eqbase); + } + + auto a_derivation_clause_containing_only_show_and_eqbase_is_less_than_or_eqbaseual_to_one_containing_only_show_and_eqbase() -> void + { + auto show_and_eqbase = deriving(nt::Show, nt::EqBase); + auto also_show_and_eqbase = deriving(nt::Show, nt::EqBase); + + ASSERT(show_and_eqbase <= also_show_and_eqbase); + } + + auto a_derivation_clause_containing_only_arithmetic_is_neither_less_than_nor_eqbaseual_to_on_containing_only_show_and_eqbase() -> void + { + auto arithmetic = deriving(nt::Arithmetic); + auto show_and_eqbase = deriving(nt::Show, nt::EqBase); + + ASSERT(!(arithmetic <= show_and_eqbase)); + } + +} // namespace less_than_or_eqbaseual_tests + +inline namespace greater_than_or_eqbaseual_tests +{ + + auto a_derivation_clause_containing_only_show_and_eqbase_is_greater_than_or_eqbaseual_to_one_containing_only_show() -> void + { + auto only_show = deriving(nt::Show); + auto show_and_eqbase = deriving(nt::Show, nt::EqBase); + + ASSERT(show_and_eqbase >= only_show); + } + + auto a_derivation_clause_containing_only_show_and_eqbase_is_greater_than_or_eqbaseual_to_one_containing_only_show_and_eqbase() -> void + { + auto show_and_eqbase = deriving(nt::Show, nt::EqBase); + auto also_show_and_eqbase = deriving(nt::Show, nt::EqBase); + + ASSERT(show_and_eqbase >= also_show_and_eqbase); + } + + auto a_derivation_clause_containing_only_show_and_eqbase_is_neither_greater_than_nor_eqbaseual_to_on_containing_only_arithmetic() -> void + { + auto arithmetic = deriving(nt::Arithmetic); + auto show_and_eqbase = deriving(nt::Show, nt::EqBase); + + ASSERT(!(show_and_eqbase >= arithmetic)); + } + +} // namespace greater_than_or_eqbaseual_tests + +auto derivation_clause_suite() -> std::pair +{ + return { + { + /// Subset tests + KAWAII(an_empty_derivation_clause_does_not_contain_any_derivable), + KAWAII(a_derivation_clause_containing_only_show_does_not_contain_eqbase), + KAWAII(a_derivation_clause_containing_only_show_does_contain_show), + KAWAII(a_derivation_clause_containing_only_show_and_eqbase_does_contain_show), + KAWAII(a_derivation_clause_containing_only_show_and_eqbase_does_contain_both_show_and_eqbase), + KAWAII(a_derivation_clause_containing_only_show_and_eqbase_does_not_contain_arithmetic), + KAWAII(a_derivation_clause_containing_only_show_and_eqbase_does_not_contain_both_show_and_arithmetic), + + /// Less-than tests + KAWAII(a_derivation_clause_containing_only_show_compares_less_than_one_containing_show_and_eqbase), + KAWAII(a_derivation_clause_containing_only_show_and_eqbase_does_not_compare_less_than_one_containing_show_and_eqbase), + KAWAII(a_derivation_clause_containing_only_show_and_eqbase_does_not_compare_less_than_one_containing_eqbase_and_show), + KAWAII(a_derivation_clause_containing_only_show_does_not_compare_less_than_one_containing_only_eqbase), + + /// Greater-than tests + KAWAII(a_derivation_clause_containing_only_show_and_eqbase_compares_greater_than_one_containing_only_show), + KAWAII(a_derivation_clause_containing_only_show_and_eqbase_does_not_compare_greater_than_one_containing_only_show_and_eqbase), + KAWAII(a_derivation_clause_containing_only_show_and_eqbase_does_not_compare_greater_than_one_containing_only_eqbase_and_show), + KAWAII(a_derivation_clause_containing_only_show_does_not_compare_greater_than_one_containing_only_eqbase), + + /// Equals tests + KAWAII(a_derivation_clause_containing_only_show_and_eqbase_is_eqbaseual_to_one_containing_only_show_and_eqbase), + KAWAII(a_derivation_clause_containing_only_show_and_eqbase_is_eqbaseual_to_one_containing_only_eqbase_and_show), + KAWAII(a_derivation_clause_containing_only_show_and_eqbase_is_not_eqbaseual_to_one_containing_only_arithmetic), + KAWAII(a_derivation_clause_containing_only_show_is_not_eqbaseual_to_one_containing_only_arithmetic), + + /// Not-Equals tests + KAWAII(a_derivation_clause_containing_only_show_and_eqbase_is_not_not_eqbaseual_to_one_containing_only_show_and_eqbase), + KAWAII(a_derivation_clause_containing_only_show_and_eqbase_is_not_not_eqbaseual_to_one_containing_only_eqbase_and_show), + KAWAII(a_derivation_clause_containing_only_eqbase_and_show_is_not_eqbaseual_to_one_containing_only_arithmetic), + KAWAII(a_derivation_clause_containing_only_eqbase_is_not_eqbaseual_to_one_containing_only_arithmetic), + + /// Less-than or Equals tests + KAWAII(a_derivation_clause_containing_only_show_is_less_than_or_eqbaseual_to_one_containing_only_show_and_eqbase), + KAWAII(a_derivation_clause_containing_only_show_and_eqbase_is_less_than_or_eqbaseual_to_one_containing_only_show_and_eqbase), + KAWAII(a_derivation_clause_containing_only_arithmetic_is_neither_less_than_nor_eqbaseual_to_on_containing_only_show_and_eqbase), + + /// Greater-than or Equals tests + KAWAII(a_derivation_clause_containing_only_show_and_eqbase_is_greater_than_or_eqbaseual_to_one_containing_only_show), + KAWAII(a_derivation_clause_containing_only_show_and_eqbase_is_greater_than_or_eqbaseual_to_one_containing_only_show_and_eqbase), + KAWAII(a_derivation_clause_containing_only_show_and_eqbase_is_neither_greater_than_nor_eqbaseual_to_on_containing_only_arithmetic), + }, + "Derivation Clause Tests"}; +} \ No newline at end of file diff --git a/source/tests/src/equality_comparison_suite.cpp b/source/tests/src/equality_comparison_suite.cpp new file mode 100644 index 0000000..4e484f4 --- /dev/null +++ b/source/tests/src/equality_comparison_suite.cpp @@ -0,0 +1,188 @@ +#include "equality_comparison_suite.hpp" + +#include "kawaii.hpp" +#include "newtype/derivable.hpp" +#include "newtype/deriving.hpp" +#include "newtype/newtype.hpp" + +#include + +#include +#include +#include + +inline namespace basic_equality_comparsion_tests +{ + + auto two_instances_of_the_same_new__type_with_the_same_value_compare_equal() -> void + { + using type_alias = nt::new_type; + + auto constexpr lhs = type_alias{42}; + auto constexpr rhs = type_alias{42}; + + ASSERT_EQUAL(lhs, rhs); + } + + auto two_instances_of_the_same_new__type_with_the_same_value_do_not_compare_not_equal() -> void + { + using type_alias = nt::new_type; + + auto constexpr lhs = type_alias{42}; + auto constexpr rhs = type_alias{42}; + + ASSERT(!(lhs != rhs)); + } + + auto two_instances_of_the_same_new__type_with_differing_values_do_compare_not_equal() -> void + { + using type_alias = nt::new_type; + + auto constexpr lhs = type_alias{42}; + auto constexpr rhs = type_alias{43}; + + ASSERT_NOT_EQUAL_TO(lhs, rhs); + } + + auto two_instances_of_the_same_new__type_with_differing_values_do_not_compare_equal() -> void + { + using type_alias = nt::new_type; + + auto constexpr lhs = type_alias{42}; + auto constexpr rhs = type_alias{43}; + + ASSERT(!(lhs == rhs)); + } + +} // namespace basic_equality_comparsion_tests + +inline namespace equality_comparsion_noexcept_tests +{ + + auto equality_comparison_on_a_new__type_is_noexcept_if_the_base_type_is_noexcept_comparable() -> void + { + using type_alias = nt::new_type; + static_assert(noexcept(std::declval() == std::declval()), "Sanity Check"); + ASSERT(noexcept(std::declval() == std::declval())); + } + + auto equality_comparison_on_a_new__type_is_not_noexcept_if_the_base_type_is_not_noexcept_comparable() -> void + { + struct strange_type + { + auto constexpr operator==(strange_type const &) const noexcept(false) -> bool + { + return false; + } + }; + + using type_alias = nt::new_type; + static_assert(!noexcept(std::declval() == std::declval()), "Sanity Check"); + ASSERT(!noexcept(std::declval() == std::declval())); + } + + auto inequality_comparison_on_a_new__type_is_noexcept_if_the_base_type_is_noexcept_comparable() -> void + { + using type_alias = nt::new_type; + static_assert(noexcept(std::declval() != std::declval()), "Sanity Check"); + ASSERT(noexcept(std::declval() != std::declval())); + } + + auto inequality_comparison_on_a_new__type_is_not_noexcept_if_the_base_type_is_not_noexcept_comparable() -> void + { + struct strange_type + { + auto constexpr operator!=(strange_type const &) const noexcept(false) -> bool + { + return false; + } + }; + + using type_alias = nt::new_type; + static_assert(!noexcept(std::declval() != std::declval()), "Sanity Check"); + ASSERT(!noexcept(std::declval() != std::declval())); + } + +} // namespace equality_comparsion_noexcept_tests + +inline namespace equality_comparison_return_type_tests +{ + + auto equality_comparsion_of_two_new__type_instances_returns_bool() -> void + { + using type_alias = nt::new_type; + ASSERT((std::is_same_v() == std::declval())>)); + } + + auto inequality_comparsion_of_two_new__type_instances_returns_bool() -> void + { + using type_alias = nt::new_type; + ASSERT((std::is_same_v() != std::declval())>)); + } + +} // namespace equality_comparison_return_type_tests + +inline namespace base_type_equality_comparison_tests +{ + + auto an_instance_of_a_new__type_compares_equal_to_an_instance_of_its_base_type_with_the_same_value() -> void + { + using type_alias = nt::new_type; + auto lhs = type_alias{42}; + auto rhs = 42; + ASSERT_EQUAL(lhs, rhs); + } + + auto an_instance_of_the_base_type_of_a_new__type_compares_equal_to_an_instance_of_the_new__type_with_the_same_value() -> void + { + using type_alias = nt::new_type; + auto lhs = 42; + auto rhs = type_alias{42}; + ASSERT_EQUAL(lhs, rhs); + } + + auto an_instance_of_a_new__type_compares_not_equal_to_an_instance_of_its_base_type_with_a_differing_value() -> void + { + using type_alias = nt::new_type; + auto lhs = type_alias{42}; + auto rhs = 43; + ASSERT(lhs != rhs); + } + + auto an_instance_of_the_base_type_of_a_new__type_compares_not_equal_to_an_instance_of_the_new__type_with_a_differing_value() -> void + { + using type_alias = nt::new_type; + auto lhs = 43; + auto rhs = type_alias{42}; + ASSERT(lhs != rhs); + } + +} // namespace base_type_equality_comparison_tests + +auto equality_comparison_suite() -> std::pair +{ + return {{ + // Basic Equality Comparison Tests + KAWAII(two_instances_of_the_same_new__type_with_the_same_value_compare_equal), + KAWAII(two_instances_of_the_same_new__type_with_the_same_value_do_not_compare_not_equal), + KAWAII(two_instances_of_the_same_new__type_with_differing_values_do_compare_not_equal), + KAWAII(two_instances_of_the_same_new__type_with_differing_values_do_not_compare_equal), + + // Equality Comparison noexcept Tests + KAWAII(equality_comparison_on_a_new__type_is_noexcept_if_the_base_type_is_noexcept_comparable), + KAWAII(equality_comparison_on_a_new__type_is_not_noexcept_if_the_base_type_is_not_noexcept_comparable), + KAWAII(inequality_comparison_on_a_new__type_is_noexcept_if_the_base_type_is_noexcept_comparable), + KAWAII(inequality_comparison_on_a_new__type_is_not_noexcept_if_the_base_type_is_not_noexcept_comparable), + + // Equality Comparison Return Type Tests + KAWAII(equality_comparsion_of_two_new__type_instances_returns_bool), + KAWAII(inequality_comparsion_of_two_new__type_instances_returns_bool), + + // Base-type Equality Comparison Tests + KAWAII(an_instance_of_a_new__type_compares_equal_to_an_instance_of_its_base_type_with_the_same_value), + KAWAII(an_instance_of_the_base_type_of_a_new__type_compares_equal_to_an_instance_of_the_new__type_with_the_same_value), + KAWAII(an_instance_of_a_new__type_compares_not_equal_to_an_instance_of_its_base_type_with_a_differing_value), + KAWAII(an_instance_of_the_base_type_of_a_new__type_compares_not_equal_to_an_instance_of_the_new__type_with_a_differing_value), + }, + "Equality Comparison Tests"}; +} \ No newline at end of file diff --git a/source/tests/src/hash_suite.cpp b/source/tests/src/hash_suite.cpp new file mode 100644 index 0000000..b482414 --- /dev/null +++ b/source/tests/src/hash_suite.cpp @@ -0,0 +1,69 @@ +#include "hash_suite.hpp" + +#include "kawaii.hpp" +#include "newtype/derivable.hpp" +#include "newtype/deriving.hpp" +#include "newtype/impl/type_traits_extensions.hpp" +#include "newtype/newtype.hpp" + +#include + +#include + +inline namespace hashable_tests +{ + + auto a_new__type_that_does_not_include_hash_in_its_derivation_clause_is_not_hashable() -> void + { + using type_alias = nt::new_type; + ASSERT(!nt::impl::is_hashable_v); + } + + auto a_new__type_that_does_include_hash_in_its_derivation_clause_is_hashable() -> void + { + static_assert(nt::impl::is_hashable_v, "Sanity Check"); + using type_alias = nt::new_type; + ASSERT(nt::impl::is_hashable_v); + } + + auto a_new__type_that_does_include_hash_in_its_derivation_clause_but_whose_base_type_is_not_hashable_is_also_not_hashable() -> void + { + struct not_hashable + { + }; + + static_assert(!nt::impl::is_hashable_v, "Sanity Check"); + using type_alias = nt::new_type; + ASSERT(!nt::impl::is_hashable_v); + } + +} // namespace hashable_tests + +inline namespace usage_tests +{ + + auto a_new__type_that_is_hashable_can_be_used_in_an_unordered__map() -> void + { + static_assert(nt::impl::is_hashable_v, "Sanity Check"); + using type_alias = nt::new_type; + + auto map = std::unordered_map{}; + map[type_alias{42}] = 43; + ASSERT_EQUAL(43, map[type_alias{42}]); + } + +} // namespace usage_tests + +auto hash_suite() -> std::pair +{ + return {{ + // Hashable Tests + KAWAII(a_new__type_that_does_not_include_hash_in_its_derivation_clause_is_not_hashable), + KAWAII(a_new__type_that_does_include_hash_in_its_derivation_clause_is_hashable), + KAWAII(a_new__type_that_does_include_hash_in_its_derivation_clause_but_whose_base_type_is_not_hashable_is_also_not_hashable), + + // Usage Tests + KAWAII(a_new__type_that_is_hashable_can_be_used_in_an_unordered__map), + }, + "std::hash Support Tests"}; +} \ No newline at end of file diff --git a/source/tests/src/io_operators_suite.cpp b/source/tests/src/io_operators_suite.cpp new file mode 100644 index 0000000..4e146a7 --- /dev/null +++ b/source/tests/src/io_operators_suite.cpp @@ -0,0 +1,121 @@ +#include "io_operators_suite.hpp" + +#include "kawaii.hpp" +#include "newtype/derivable.hpp" +#include "newtype/deriving.hpp" +#include "newtype/newtype.hpp" + +#include + +#include +#include +#include +#include +#include + +inline namespace traits_extensions +{ + + template + struct has_stream_input : std::false_type + { + }; + + template + struct has_stream_input() >> std::declval())>> : std::true_type + { + }; + + template + auto constexpr has_stream_input_v = has_stream_input::value; + + template + struct has_stream_output : std::false_type + { + }; + + template + struct has_stream_output() << std::declval())>> : std::true_type + { + }; + + template + auto constexpr has_stream_output_v = has_stream_output::value; + +} // namespace traits_extensions + +inline namespace stream_input_operator_tests +{ + + auto a_new__type_has_the_stream_input_operator_if_the_derivation_clause_contains_read() -> void + { + using type_alias = nt::new_type; + ASSERT(has_stream_input_v); + } + + auto a_new__type_does_not_have_the_stream_input_operator_if_the_derivation_clause_does_not_contain_read() -> void + { + using type_alias = nt::new_type; + ASSERT(!has_stream_input_v); + } + + auto a_instance_of_a_new__type_can_be_read_from_an_istream_if_the_base_type_can_be_read_from_an_istream() -> void + { + static_assert(has_stream_input_v, "Sanity Check"); + using type_alias = nt::new_type; + + auto obj = type_alias{}; + auto input = std::istringstream{"42"}; + + input >> obj; + + ASSERT_EQUAL(42, obj.decay()); + } + +} // namespace stream_input_operator_tests + +inline namespace stream_output_operator_tests +{ + + auto a_new__type_has_the_stream_output_operator_if_the_derivation_clause_contains_show() -> void + { + using type_alias = nt::new_type; + ASSERT(has_stream_output_v); + } + + auto a_new__type_does_not_have_the_stream_output_operator_if_the_derivation_clause_does_not_contain_show() -> void + { + using type_alias = nt::new_type; + ASSERT(!has_stream_output_v); + } + + auto a_instance_of_a_new__type_can_be_written_to_an_ostream_if_the_base_type_can_be_written_to_an_ostream() -> void + { + static_assert(has_stream_output_v, "Sanity Check"); + using type_alias = nt::new_type; + + auto obj = type_alias{42}; + auto output = std::ostringstream{}; + + output << obj; + + ASSERT_EQUAL("42", output.str()); + } + +} // namespace stream_output_operator_tests + +auto io_operators_suite() -> std::pair +{ + return {{ + // Stream Input Operator Tests + KAWAII(a_new__type_has_the_stream_input_operator_if_the_derivation_clause_contains_read), + KAWAII(a_new__type_does_not_have_the_stream_input_operator_if_the_derivation_clause_does_not_contain_read), + KAWAII(a_instance_of_a_new__type_can_be_read_from_an_istream_if_the_base_type_can_be_read_from_an_istream), + + // Stream Ouput Operator Tests + KAWAII(a_new__type_has_the_stream_output_operator_if_the_derivation_clause_contains_show), + KAWAII(a_new__type_does_not_have_the_stream_output_operator_if_the_derivation_clause_does_not_contain_show), + KAWAII(a_instance_of_a_new__type_can_be_written_to_an_ostream_if_the_base_type_can_be_written_to_an_ostream), + }, + "I/O Operators Tests"}; +} \ No newline at end of file diff --git a/source/tests/src/iterable_suite.cpp b/source/tests/src/iterable_suite.cpp new file mode 100644 index 0000000..add4696 --- /dev/null +++ b/source/tests/src/iterable_suite.cpp @@ -0,0 +1,719 @@ +#include "iterable_suite.hpp" + +#include "kawaii.hpp" +#include "newtype/derivable.hpp" +#include "newtype/deriving.hpp" +#include "newtype/impl/type_traits_extensions.hpp" +#include "newtype/newtype.hpp" + +#include + +#include +#include +#include +#include + +namespace +{ + + struct with_member + { + using iterator = char *; + using const_iterator = char const *; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + auto begin() -> iterator; + auto begin() const -> const_iterator; + auto cbegin() const -> const_iterator; + auto rbegin() -> reverse_iterator; + auto rbegin() const -> const_reverse_iterator; + auto crbegin() const -> const_reverse_iterator; + + auto end() -> iterator; + auto end() const -> const_iterator; + auto cend() const -> const_iterator; + auto rend() -> reverse_iterator; + auto rend() const -> const_reverse_iterator; + auto crend() const -> const_reverse_iterator; + }; + + struct with_free + { + using iterator = char *; + using const_iterator = char const *; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + }; + + auto begin(with_free &) -> with_free::iterator + { + return {}; + } + + auto begin(with_free const &) -> with_free::const_iterator + { + return {}; + } + + auto cbegin(with_free const &) -> with_free::const_iterator + { + return {}; + } + + auto rbegin(with_free &) -> with_free::reverse_iterator + { + return {}; + } + + auto rbegin(with_free const &) -> with_free::const_reverse_iterator + { + return {}; + } + + auto crbegin(with_free const &) -> with_free::const_reverse_iterator + { + return {}; + } + + auto end(with_free &) -> with_free::iterator + { + return {}; + } + + auto end(with_free const &) -> with_free::const_iterator + { + return {}; + } + + auto cend(with_free const &) -> with_free::const_iterator + { + return {}; + } + + auto rend(with_free &) -> with_free::reverse_iterator + { + return {}; + } + + auto rend(with_free const &) -> with_free::const_reverse_iterator + { + return {}; + } + + auto crend(with_free const &) -> with_free::const_reverse_iterator + { + return {}; + } + +} // namespace + +inline namespace combined_enablement_tests +{ + + auto a_new__type_not_deriving_iterable_has_no_begin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_begin_v)); + } + + auto a_new__type_not_deriving_iterable_has_no_constant_begin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_begin_v)); + } + + auto a_new__type_not_deriving_iterable_has_no_cbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_cbegin_v)); + } + + auto a_new__type_not_deriving_iterable_has_no_rbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_rbegin_v)); + } + + auto a_new__type_not_deriving_iterable_has_no_constant_rbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_rbegin_v)); + } + + auto a_new__type_not_deriving_iterable_has_no_crbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_crbegin_v)); + } + + auto a_new__type_not_deriving_iterable_has_no_end() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_end_v)); + } + + auto a_new__type_not_deriving_iterable_has_no_constant_end() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_end_v)); + } + + auto a_new__type_not_deriving_iterable_has_no_cend() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_cend_v)); + } + + auto a_new__type_not_deriving_iterable_has_no_rend() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_rend_v)); + } + + auto a_new__type_not_deriving_iterable_has_no_constant_rend() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_rend_v)); + } + + auto a_new__type_not_deriving_iterable_has_no_crend() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_crend_v)); + } + + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_begin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_begin_v)); + } + + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_constant_begin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_begin_v)); + } + + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_cbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_cbegin_v)); + } + + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_rbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_rbegin_v)); + } + + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_constant_rbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_rbegin_v)); + } + + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_crbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_crbegin_v)); + } + + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_end() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_end_v)); + } + + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_constant_end() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_end_v)); + } + + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_cend() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_cend_v)); + } + + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_rend() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_rend_v)); + } + + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_constant_rend() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_rend_v)); + } + + auto a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_crend() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_crend_v)); + } + +} // namespace combined_enablement_tests + +inline namespace member_enablement_tests +{ + + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_begin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_member_begin_v)); + } + + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_constant_begin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_member_begin_v)); + } + + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_cbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_member_cbegin_v)); + } + + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_rbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_member_rbegin_v)); + } + + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_constant_rbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_member_rbegin_v)); + } + + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_crbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_member_crbegin_v)); + } + + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_end() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_member_end_v)); + } + + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_constant_end() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_member_end_v)); + } + + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_cend() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_member_cend_v)); + } + + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_rend() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_member_rend_v)); + } + + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_constant_rend() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_member_rend_v)); + } + + auto a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_crend() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_member_crend_v)); + } + + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_begin() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_member_begin_v); + } + + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_constant_begin() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_member_begin_v); + } + + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_cbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_member_cbegin_v); + } + + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_rbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_member_rbegin_v); + } + + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_constant_rbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_member_rbegin_v); + } + + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_crbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_member_crbegin_v); + } + + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_end() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_member_end_v); + } + + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_constant_end() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_member_end_v); + } + + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_cend() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_member_cend_v); + } + + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_rend() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_member_rend_v); + } + + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_constant_rend() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_member_rend_v); + } + + auto a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_crend() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_member_crend_v); + } + +} // namespace member_enablement_tests + +inline namespace free_enablement_tests +{ + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_begin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_free_begin_v)); + } + + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_constant_begin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_free_begin_v)); + } + + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_cbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_free_cbegin_v)); + } + + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_rbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_free_rbegin_v)); + } + + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_constant_rbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_free_rbegin_v)); + } + + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_crbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_free_crbegin_v)); + } + + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_end() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_free_end_v)); + } + + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_constant_end() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_free_end_v)); + } + + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_cend() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_free_cend_v)); + } + + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_rend() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_free_rend_v)); + } + + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_constant_rend() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_free_rend_v)); + } + + auto a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_crend() -> void + { + using type_alias = nt::new_type; + ASSERT(!(nt::impl::has_free_crend_v)); + } + + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_begin() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_free_begin_v); + } + + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_constant_begin() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_free_begin_v); + } + + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_cbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_free_cbegin_v); + } + + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_rbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_free_rbegin_v); + } + + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_constant_rbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_free_rbegin_v); + } + + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_crbegin() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_free_crbegin_v); + } + + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_end() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_free_end_v); + } + + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_constant_end() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_free_end_v); + } + + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_cend() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_free_cend_v); + } + + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_rend() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_free_rend_v); + } + + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_constant_rend() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_free_rend_v); + } + + auto a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_crend() -> void + { + using type_alias = nt::new_type; + ASSERT(nt::impl::has_free_crend_v); + } + +} // namespace free_enablement_tests + +inline namespace semantic_tests +{ + + auto a_non_const_object_of_iterable_new__type_can_be_used_in_value_range_for() -> void + { + using type_alias = nt::new_type, struct tag, deriving(nt::Iterable)>; + auto object = type_alias{{1, 2, 3}}; + for (auto e : object) + { + (void)e; + } + ASSERT(true); + } + + auto a_const_object_of_iterable_new__type_can_be_used_in_value_range_for() -> void + { + using type_alias = nt::new_type, struct tag, deriving(nt::Iterable)>; + auto const object = type_alias{{1, 2, 3}}; + for (auto e : object) + { + (void)e; + } + ASSERT(true); + } + + auto a_non_const_object_of_iterable_new__type_can_be_used_in_reference_range_for() -> void + { + using type_alias = nt::new_type, struct tag, deriving(nt::Iterable)>; + auto object = type_alias{{1, 2, 3}}; + for (auto & e : object) + { + (void)e; + } + ASSERT(true); + } + + auto a_const_object_of_iterable_new__type_can_be_used_in_const_reference_range_for() -> void + { + using type_alias = nt::new_type, struct tag, deriving(nt::Iterable)>; + auto const object = type_alias{{1, 2, 3}}; + for (auto const & e : object) + { + (void)e; + } + ASSERT(true); + } + + auto applying_accumulate_to_an_interable_new__type_yields_the_same_result_as_when_applied_to_the_base_type() -> void + { + using type_alias = nt::new_type, struct tag, deriving(nt::Iterable)>; + auto const nt_object = type_alias{{1, 2, 3}}; + auto const bt_object = type_alias::base_type{1, 2, 3}; + + auto nt_result = std::accumulate(std::cbegin(nt_object), std::cend(nt_object), 0); + auto bt_result = std::accumulate(std::cbegin(bt_object), std::cend(bt_object), 0); + + ASSERT_EQUAL(bt_result, nt_result); + } + + auto iterating_over_an_iterable_new__type_yields_the_elements_in_the_same_order_as_when_iterating_the_base_type() -> void + { + using std::cbegin, std::cend, std::equal; + using type_alias = nt::new_type, struct tag, deriving(nt::Iterable)>; + auto const nt_object = type_alias{{1, 2, 3}}; + auto const bt_object = type_alias::base_type{1, 2, 3}; + + ASSERT(equal(cbegin(nt_object), cend(nt_object), cbegin(bt_object), cend(bt_object))); + } + +} // namespace semantic_tests + +auto iterable_suite() -> std::pair +{ + return {{ + /// Combined Enablement Tests + KAWAII(a_new__type_not_deriving_iterable_has_no_begin), + KAWAII(a_new__type_not_deriving_iterable_has_no_constant_begin), + KAWAII(a_new__type_not_deriving_iterable_has_no_cbegin), + KAWAII(a_new__type_not_deriving_iterable_has_no_rbegin), + KAWAII(a_new__type_not_deriving_iterable_has_no_constant_rbegin), + KAWAII(a_new__type_not_deriving_iterable_has_no_crbegin), + KAWAII(a_new__type_not_deriving_iterable_has_no_end), + KAWAII(a_new__type_not_deriving_iterable_has_no_constant_end), + KAWAII(a_new__type_not_deriving_iterable_has_no_cend), + KAWAII(a_new__type_not_deriving_iterable_has_no_rend), + KAWAII(a_new__type_not_deriving_iterable_has_no_constant_rend), + KAWAII(a_new__type_not_deriving_iterable_has_no_crend), + KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_begin), + KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_constant_begin), + KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_cbegin), + KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_rbegin), + KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_constant_rbegin), + KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_crbegin), + KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_end), + KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_constant_end), + KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_cend), + KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_rend), + KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_constant_rend), + KAWAII(a_new__type_on_a_non_iterable_type_deriving_iterable_has_no_crend), + + /// Member Enablement Tests + KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_begin), + KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_constant_begin), + KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_cbegin), + KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_rbegin), + KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_constant_rbegin), + KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_crbegin), + KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_end), + KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_constant_end), + KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_cend), + KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_rend), + KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_constant_rend), + KAWAII(a_new__type_on_a_non_member_iterable_type_deriving_iterable_has_no_member_crend), + KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_begin), + KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_constant_begin), + KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_cbegin), + KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_rbegin), + KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_constant_rbegin), + KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_crbegin), + KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_end), + KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_constant_end), + KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_cend), + KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_rend), + KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_constant_rend), + KAWAII(a_new__type_on_a_member_iterable_type_deriving_iterable_has_member_crend), + + /// Free Enablement Tests + KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_begin), + KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_constant_begin), + KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_cbegin), + KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_rbegin), + KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_constant_rbegin), + KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_crbegin), + KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_end), + KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_constant_end), + KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_cend), + KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_rend), + KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_constant_rend), + KAWAII(a_new__type_on_a_non_free_iterable_type_deriving_iterable_has_no_free_crend), + KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_begin), + KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_constant_begin), + KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_cbegin), + KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_rbegin), + KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_constant_rbegin), + KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_crbegin), + KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_end), + KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_constant_end), + KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_cend), + KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_rend), + KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_constant_rend), + KAWAII(a_new__type_on_a_free_iterable_type_deriving_iterable_has_free_crend), + + /// Semantic Tests + KAWAII(a_non_const_object_of_iterable_new__type_can_be_used_in_value_range_for), + KAWAII(a_const_object_of_iterable_new__type_can_be_used_in_value_range_for), + KAWAII(a_non_const_object_of_iterable_new__type_can_be_used_in_reference_range_for), + KAWAII(a_const_object_of_iterable_new__type_can_be_used_in_const_reference_range_for), + KAWAII(applying_accumulate_to_an_interable_new__type_yields_the_same_result_as_when_applied_to_the_base_type), + KAWAII(iterating_over_an_iterable_new__type_yields_the_elements_in_the_same_order_as_when_iterating_the_base_type), + }, + + "Iterable Tests"}; +} \ No newline at end of file diff --git a/source/tests/src/new_type_constructor_suite.cpp b/source/tests/src/new_type_constructor_suite.cpp new file mode 100644 index 0000000..fc3e9f6 --- /dev/null +++ b/source/tests/src/new_type_constructor_suite.cpp @@ -0,0 +1,91 @@ +#include "new_type_constructor_suite.hpp" + +#include "kawaii.hpp" +#include "newtype/derivable.hpp" +#include "newtype/newtype.hpp" + +#include + +#include + +inline namespace constructor_tests +{ + + struct not_default_constructible + { + not_default_constructible() = delete; + }; + + auto a_new__type_based_on_a_type_that_is_default_constructible_is_default_constructible_too() -> void + { + using nt_float = nt::new_type; + + ASSERT(std::is_default_constructible_v); + } + + auto a_new__type_based_on_a_type_that_is_not_default_constructible_is_not_default_constructible_too() -> void + { + using nt_not_default_constructible = nt::new_type; + + ASSERT(!std::is_default_constructible_v); + } + + template + auto a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type() -> void + { + using nt_old = nt::new_type; + + ASSERT((std::is_constructible_v)); + } + + auto a_new__type_instance_can_be_copy_constructed_if_the_base_type_can_be_copy_constructed() -> void + { + using type_alias = nt::new_type; + ASSERT((std::is_copy_constructible_v)); + } + + auto a_new__type_instance_can_not_be_copy_constructed_if_the_base_type_can_not_be_copy_constructed() -> void + { + struct not_copy_constructible + { + not_copy_constructible() = default; + not_copy_constructible(not_copy_constructible const &) = delete; + not_copy_constructible(not_copy_constructible &&) = default; + auto operator=(not_copy_constructible const &) -> not_copy_constructible & = default; + auto operator=(not_copy_constructible &&) -> not_copy_constructible & = default; + }; + + using type_alias = nt::new_type; + ASSERT(!(std::is_copy_constructible_v)); + } + +} // namespace constructor_tests + +auto new_type_constructor_suite() -> std::pair +{ + return {{ + KAWAII(a_new__type_based_on_a_type_that_is_default_constructible_is_default_constructible_too), + KAWAII(a_new__type_based_on_a_type_that_is_not_default_constructible_is_not_default_constructible_too), + KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), + KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), + KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), + KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), + KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), + KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), + KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), + KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), + KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), + KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), + KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), + KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), + KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), + KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), + KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), + KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), + KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), + KAWAII(a_new__type_based_on_a_fundamental_type_can_be_constructed_with_a_value_of_fundamental_type), + KAWAII(a_new__type_instance_can_be_copy_constructed_if_the_base_type_can_be_copy_constructed), + KAWAII(a_new__type_instance_can_not_be_copy_constructed_if_the_base_type_can_not_be_copy_constructed), + }, + "new_type Constructor Tests"}; +} \ No newline at end of file diff --git a/source/tests/src/relational_operators_suite.cpp b/source/tests/src/relational_operators_suite.cpp new file mode 100644 index 0000000..64fcba0 --- /dev/null +++ b/source/tests/src/relational_operators_suite.cpp @@ -0,0 +1,321 @@ +#include "relational_operators_suite.hpp" + +#include "kawaii.hpp" +#include "newtype/derivable.hpp" +#include "newtype/deriving.hpp" +#include "newtype/newtype.hpp" + +#include + +#include +#include +#include + +inline namespace traits_extensions +{ + + template + struct has_less_than : std::false_type + { + }; + + template + struct has_less_than() < std::declval())>> : std::true_type + { + }; + + template + auto constexpr has_less_than_v = has_less_than::value; + + template + struct has_greater_than : std::false_type + { + }; + + template + struct has_greater_than() > std::declval())>> : std::true_type + { + }; + + template + auto constexpr has_greater_than_v = has_greater_than::value; + + template + struct has_less_than_equal_to : std::false_type + { + }; + + template + struct has_less_than_equal_to() <= std::declval())>> : std::true_type + { + }; + + template + auto constexpr has_less_than_equal_to_v = has_less_than_equal_to::value; + + template + struct has_greater_than_equal_to : std::false_type + { + }; + + template + struct has_greater_than_equal_to() >= std::declval())>> : std::true_type + { + }; + + template + auto constexpr has_greater_than_equal_to_v = has_greater_than_equal_to::value; + +} // namespace traits_extensions + +inline namespace relational_operator_presence_tests +{ + + auto an_instance_of_new__type_has_less_than_if_its_derivation_clause_contains_relational() -> void + { + using type_alias = nt::new_type; + ASSERT(has_less_than_v); + } + + auto an_instance_of_new__type_does_not_have_less_than_if_its_derivation_clause_does_not_contain_relational() -> void + { + using type_alias = nt::new_type; + ASSERT(!has_less_than_v); + } + + auto an_instance_of_new__type_has_greater_than_if_its_derivation_clause_contains_relational() -> void + { + using type_alias = nt::new_type; + ASSERT(has_greater_than_v); + } + + auto an_instance_of_new__type_does_not_have_greater_than_if_its_derivation_clause_does_not_contain_relational() -> void + { + using type_alias = nt::new_type; + ASSERT(!has_greater_than_v); + } + + auto an_instance_of_new__type_has_less_than_or_equal_to_if_its_derivation_clause_contains_relational() -> void + { + using type_alias = nt::new_type; + ASSERT(has_less_than_equal_to_v); + } + + auto an_instance_of_new__type_does_not_have_less_than_or_equal_to_if_its_derivation_clause_does_not_contain_relational() -> void + { + using type_alias = nt::new_type; + ASSERT(!has_less_than_equal_to_v); + } + + auto an_instance_of_new__type_has_greater_than_or_equal_to_if_its_derivation_clause_contains_relational() -> void + { + using type_alias = nt::new_type; + ASSERT(has_greater_than_equal_to_v); + } + + auto an_instance_of_new__type_does_not_have_greater_than_or_equal_to_if_its_derivation_clause_does_not_contain_relational() -> void + { + using type_alias = nt::new_type; + ASSERT(!has_greater_than_equal_to_v); + } + +} // namespace relational_operator_presence_tests + +inline namespace less_than_tests +{ + + auto two_instances_of_the_same_new__type_compare_less_than_if_both_contained_values_would_compare_less_than() -> void + { + using type_alias = nt::new_type; + auto constexpr lhs{21}; + auto constexpr rhs{42}; + static_assert(lhs < rhs, "Sanity Check"); + ASSERT_LESS(type_alias{lhs}, type_alias{rhs}); + } + + auto two_instances_of_the_same_new__type_do_not_compare_less_than_if_both_contained_values_would_not_compare_less_than() -> void + { + using type_alias = nt::new_type; + auto constexpr lhs{44}; + auto constexpr rhs{42}; + static_assert(!(lhs < rhs), "Sanity Check"); + ASSERT(!(type_alias{lhs} < type_alias{rhs})); + } + + auto two_instances_of_the_same_new__type_compare_less_than_or_equal_if_both_contained_values_would_compare_less_than_or_equal() -> void + { + using type_alias = nt::new_type; + auto constexpr lhs{33}; + auto constexpr rhs{42}; + static_assert(lhs <= rhs, "Sanity Check"); + ASSERT_LESS_EQUAL(type_alias{lhs}, type_alias{rhs}); + } + + auto two_instances_of_the_same_new__type_do_not_compare_less_than_or_equal_if_both_contained_values_would_not_compare_less_than_or_equal() + -> void + { + using type_alias = nt::new_type; + auto constexpr lhs{87}; + auto constexpr rhs{42}; + static_assert(!(lhs < rhs), "Sanity Check"); + ASSERT(!(type_alias{lhs} < type_alias{rhs})); + } + +} // namespace less_than_tests + +inline namespace greater_than_tests +{ + + auto two_instances_of_the_same_new__type_compare_greater_than_if_both_contained_values_would_compare_greater_than() -> void + { + using type_alias = nt::new_type; + auto constexpr lhs{42}; + auto constexpr rhs{21}; + static_assert(lhs > rhs, "Sanity Check"); + ASSERT_GREATER(type_alias{lhs}, type_alias{rhs}); + } + + auto two_instances_of_the_same_new__type_do_not_compare_greater_than_if_both_contained_values_would_not_compare_greater_than() -> void + { + using type_alias = nt::new_type; + auto constexpr lhs{42}; + auto constexpr rhs{44}; + static_assert(!(lhs > rhs), "Sanity Check"); + ASSERT(!(type_alias{lhs} > type_alias{rhs})); + } + + auto two_instances_of_the_same_new__type_compare_greater_than_or_equal_if_both_contained_values_would_compare_greater_than_or_equal() -> void + { + using type_alias = nt::new_type; + auto constexpr lhs{42}; + auto constexpr rhs{33}; + static_assert(lhs >= rhs, "Sanity Check"); + ASSERT_GREATER_EQUAL(type_alias{lhs}, type_alias{rhs}); + } + + auto + two_instances_of_the_same_new__type_do_not_compare_greater_than_or_equal_if_both_contained_values_would_not_compare_greater_than_or_equal() + -> void + { + using type_alias = nt::new_type; + auto constexpr lhs{42}; + auto constexpr rhs{87}; + static_assert(!(lhs > rhs), "Sanity Check"); + ASSERT(!(type_alias{lhs} > type_alias{rhs})); + } + +} // namespace greater_than_tests + +inline namespace relational_operator_noexcept_tests +{ + + struct strange_type + { + auto constexpr operator<(strange_type const & other) const noexcept(false) -> bool; + auto constexpr operator>(strange_type const & other) const noexcept(false) -> bool; + auto constexpr operator<=(strange_type const & other) const noexcept(false) -> bool; + auto constexpr operator>=(strange_type const & other) const noexcept(false) -> bool; + }; + + auto less_than_comparison_of_two_intances_of_the_same_new__type_is_noexcept_if_comparison_of_the_base_type_is_noexcept() -> void + { + using type_alias = nt::new_type; + static_assert(noexcept(std::declval() < std::declval()), "Sanity Check"); + ASSERT(noexcept(std::declval() < std::declval())); + } + + auto less_than_comparison_of_two_intances_of_the_same_new__type_is_not_noexcept_if_comparison_of_the_base_type_is_not_noexcept() -> void + { + using type_alias = nt::new_type; + static_assert(!noexcept(std::declval() < std::declval()), "Sanity Check"); + ASSERT(!noexcept(std::declval() < std::declval())); + } + + auto less_than_equal_to_comparison_of_two_intances_of_the_same_new__type_is_noexcept_if_comparison_of_the_base_type_is_noexcept() -> void + { + using type_alias = nt::new_type; + static_assert(noexcept(std::declval() <= std::declval()), "Sanity Check"); + ASSERT(noexcept(std::declval() <= std::declval())); + } + + auto less_than_equal_to_comparison_of_two_intances_of_the_same_new__type_is_not_noexcept_if_comparison_of_the_base_type_is_not_noexcept() + -> void + { + using type_alias = nt::new_type; + static_assert(!noexcept(std::declval() <= std::declval()), "Sanity Check"); + ASSERT(!noexcept(std::declval() <= std::declval())); + } + + auto greater_than_comparison_of_two_intances_of_the_same_new__type_is_noexcept_if_comparison_of_the_base_type_is_noexcept() -> void + { + using type_alias = nt::new_type; + static_assert(noexcept(std::declval() > std::declval()), "Sanity Check"); + ASSERT(noexcept(std::declval() > std::declval())); + } + + auto greater_than_comparison_of_two_intances_of_the_same_new__type_is_not_noexcept_if_comparison_of_the_base_type_is_not_noexcept() -> void + { + using type_alias = nt::new_type; + static_assert(!noexcept(std::declval() > std::declval()), "Sanity Check"); + ASSERT(!noexcept(std::declval() > std::declval())); + } + + auto greater_than_equal_to_comparison_of_two_intances_of_the_same_new__type_is_noexcept_if_comparison_of_the_base_type_is_noexcept() -> void + { + using type_alias = nt::new_type; + static_assert(noexcept(std::declval() >= std::declval()), "Sanity Check"); + ASSERT(noexcept(std::declval() >= std::declval())); + } + + auto greater_than_equal_to_comparison_of_two_intances_of_the_same_new__type_is_not_noexcept_if_comparison_of_the_base_type_is_not_noexcept() + -> void + { + using type_alias = nt::new_type; + static_assert(!noexcept(std::declval() >= std::declval()), "Sanity Check"); + ASSERT(!noexcept(std::declval() >= std::declval())); + } + +} // namespace relational_operator_noexcept_tests + +auto relational_operators_suite() -> std::pair +{ + return { + { + // clang-format off + + // Relational Operator Presensence Tests + KAWAII(an_instance_of_new__type_has_less_than_if_its_derivation_clause_contains_relational), + KAWAII(an_instance_of_new__type_does_not_have_less_than_if_its_derivation_clause_does_not_contain_relational), + KAWAII(an_instance_of_new__type_has_greater_than_if_its_derivation_clause_contains_relational), + KAWAII(an_instance_of_new__type_does_not_have_greater_than_if_its_derivation_clause_does_not_contain_relational), + KAWAII(an_instance_of_new__type_has_less_than_or_equal_to_if_its_derivation_clause_contains_relational), + KAWAII(an_instance_of_new__type_does_not_have_less_than_or_equal_to_if_its_derivation_clause_does_not_contain_relational), + KAWAII(an_instance_of_new__type_has_greater_than_or_equal_to_if_its_derivation_clause_contains_relational), + KAWAII(an_instance_of_new__type_does_not_have_greater_than_or_equal_to_if_its_derivation_clause_does_not_contain_relational), + + // Less-than Comparison Tests + KAWAII(two_instances_of_the_same_new__type_compare_less_than_if_both_contained_values_would_compare_less_than), + KAWAII(two_instances_of_the_same_new__type_do_not_compare_less_than_if_both_contained_values_would_not_compare_less_than), + KAWAII(two_instances_of_the_same_new__type_compare_less_than_or_equal_if_both_contained_values_would_compare_less_than_or_equal), + KAWAII(two_instances_of_the_same_new__type_do_not_compare_less_than_or_equal_if_both_contained_values_would_not_compare_less_than_or_equal), + + // Greater-than Comparison Tests + KAWAII(two_instances_of_the_same_new__type_compare_greater_than_if_both_contained_values_would_compare_greater_than), + KAWAII(two_instances_of_the_same_new__type_do_not_compare_greater_than_if_both_contained_values_would_not_compare_greater_than), + KAWAII(two_instances_of_the_same_new__type_compare_greater_than_or_equal_if_both_contained_values_would_compare_greater_than_or_equal), + KAWAII(two_instances_of_the_same_new__type_do_not_compare_greater_than_or_equal_if_both_contained_values_would_not_compare_greater_than_or_equal), + + // Relational Operators noexcept Tests + KAWAII(less_than_comparison_of_two_intances_of_the_same_new__type_is_noexcept_if_comparison_of_the_base_type_is_noexcept), + KAWAII(less_than_comparison_of_two_intances_of_the_same_new__type_is_not_noexcept_if_comparison_of_the_base_type_is_not_noexcept), + KAWAII(less_than_equal_to_comparison_of_two_intances_of_the_same_new__type_is_noexcept_if_comparison_of_the_base_type_is_noexcept), + KAWAII(less_than_equal_to_comparison_of_two_intances_of_the_same_new__type_is_not_noexcept_if_comparison_of_the_base_type_is_not_noexcept), + KAWAII(greater_than_comparison_of_two_intances_of_the_same_new__type_is_noexcept_if_comparison_of_the_base_type_is_noexcept), + KAWAII(greater_than_comparison_of_two_intances_of_the_same_new__type_is_not_noexcept_if_comparison_of_the_base_type_is_not_noexcept), + KAWAII(greater_than_equal_to_comparison_of_two_intances_of_the_same_new__type_is_noexcept_if_comparison_of_the_base_type_is_noexcept), + KAWAII(greater_than_equal_to_comparison_of_two_intances_of_the_same_new__type_is_not_noexcept_if_comparison_of_the_base_type_is_not_noexcept), + + // clang-format on + }, + "Relational Operators Tests"}; +} \ No newline at end of file -- cgit v1.2.3