diff --git a/.devcontainer/armhf/Dockerfile b/.devcontainer/armhf/Dockerfile index 7d5632a6..7d555f36 100644 --- a/.devcontainer/armhf/Dockerfile +++ b/.devcontainer/armhf/Dockerfile @@ -24,7 +24,7 @@ RUN dpkg --add-architecture armhf && \ && rm -rf /var/lib/apt/lists/* # Create non-root user with stable UID/GID -ARG USERNAME=devuser +ARG USERNAME=vscode ARG USER_UID=1000 ARG USER_GID=1000 diff --git a/.devcontainer/i386/Dockerfile b/.devcontainer/i386/Dockerfile index 99223eb9..bace68cd 100644 --- a/.devcontainer/i386/Dockerfile +++ b/.devcontainer/i386/Dockerfile @@ -24,7 +24,7 @@ RUN dpkg --add-architecture i386 && \ && rm -rf /var/lib/apt/lists/* # Create non-root user with stable UID/GID -ARG USERNAME=devuser +ARG USERNAME=vscode ARG USER_UID=1000 ARG USER_GID=1000 diff --git a/.devcontainer/powerpc/Dockerfile b/.devcontainer/powerpc/Dockerfile index a74cb690..faa94096 100644 --- a/.devcontainer/powerpc/Dockerfile +++ b/.devcontainer/powerpc/Dockerfile @@ -49,7 +49,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && rm -rf /var/lib/apt/lists/* # Create non-root user with stable UID/GID -ARG USERNAME=devuser +ARG USERNAME=vscode ARG USER_UID=1000 ARG USER_GID=1000 diff --git a/.devcontainer/riscv64/Dockerfile b/.devcontainer/riscv64/Dockerfile index 081e42ed..7d07cdda 100644 --- a/.devcontainer/riscv64/Dockerfile +++ b/.devcontainer/riscv64/Dockerfile @@ -24,7 +24,7 @@ RUN dpkg --add-architecture riscv64 && \ && rm -rf /var/lib/apt/lists/* # Create non-root user with stable UID/GID -ARG USERNAME=devuser +ARG USERNAME=vscode ARG USER_UID=1000 ARG USER_GID=1000 diff --git a/.devcontainer/s390x/Dockerfile b/.devcontainer/s390x/Dockerfile index f8c6ff87..5656bc1d 100644 --- a/.devcontainer/s390x/Dockerfile +++ b/.devcontainer/s390x/Dockerfile @@ -24,7 +24,7 @@ RUN dpkg --add-architecture s390x && \ && rm -rf /var/lib/apt/lists/* # Create non-root user with stable UID/GID -ARG USERNAME=devuser +ARG USERNAME=vscode ARG USER_UID=1000 ARG USER_GID=1000 diff --git a/include/etl/concepts.h b/include/etl/concepts.h index ac539947..9376264b 100644 --- a/include/etl/concepts.h +++ b/include/etl/concepts.h @@ -33,6 +33,7 @@ SOFTWARE. #include "platform.h" +#include "invoke.h" #include "type_traits.h" #include "utility.h" @@ -50,12 +51,31 @@ namespace etl using std::assignable_from; using std::common_reference_with; using std::common_with; + using std::constructible_from; using std::convertible_to; + using std::copy_constructible; + using std::copyable; + using std::default_initializable; using std::derived_from; + using std::destructible; + using std::equality_comparable; + using std::equivalence_relation; using std::floating_point; using std::integral; + using std::invocable; + using std::movable; + using std::move_constructible; + using std::predicate; + using std::regular; + using std::regular_invocable; + using std::relation; using std::same_as; + using std::semiregular; using std::signed_integral; + using std::strict_weak_order; + using std::swappable; + using std::swappable_with; + using std::totally_ordered; using std::unsigned_integral; #else // not ETL_USING_STL @@ -114,6 +134,112 @@ namespace etl { lhs = etl::forward(rhs) } -> etl::same_as; }; + //*************************************************************************** + template + concept invocable = etl::is_invocable_v; + + //*************************************************************************** + template + concept regular_invocable = etl::invocable; + + //*************************************************************************** + template + concept destructible = requires(T& t) { + { t.~T() } noexcept; + }; + + //*************************************************************************** + template + concept constructible_from = etl::destructible && etl::is_constructible_v; + + //*************************************************************************** + template + concept default_initializable = etl::constructible_from && requires { + T{}; + ::new T; + }; + + //*************************************************************************** + template + concept move_constructible = etl::constructible_from && etl::convertible_to; + + //*************************************************************************** + template + concept copy_constructible = + etl::move_constructible && etl::constructible_from && etl::convertible_to && etl::constructible_from + && etl::convertible_to && etl::constructible_from && etl::convertible_to; + + //*************************************************************************** + namespace private_concepts + { + template + concept boolean_testable = etl::convertible_to && requires(T&& t) { + { !etl::forward(t) } -> etl::convertible_to; + }; + } // namespace private_concepts + + //*************************************************************************** + template + concept equality_comparable = requires(const etl::remove_reference_t& a, const etl::remove_reference_t& b) { + { a == b } -> private_concepts::boolean_testable; + { a != b } -> private_concepts::boolean_testable; + }; + + //*************************************************************************** + template + concept totally_ordered = etl::equality_comparable && requires(const etl::remove_reference_t& a, const etl::remove_reference_t& b) { + { a < b } -> private_concepts::boolean_testable; + { a > b } -> private_concepts::boolean_testable; + { a <= b } -> private_concepts::boolean_testable; + { a >= b } -> private_concepts::boolean_testable; + }; + + //*************************************************************************** + template + concept swappable = requires(T& a, T& b) { etl::swap(a, b); }; + + //*************************************************************************** + template + concept swappable_with = etl::common_reference_with&, etl::remove_reference_t&> && requires(T&& t, U&& u) { + etl::swap(etl::forward(t), etl::forward(t)); + etl::swap(etl::forward(u), etl::forward(u)); + etl::swap(etl::forward(t), etl::forward(u)); + etl::swap(etl::forward(u), etl::forward(t)); + }; + + //*************************************************************************** + template + concept movable = etl::is_object_v && etl::move_constructible && etl::assignable_from && etl::swappable; + + //*************************************************************************** + template + concept copyable = etl::copy_constructible && etl::movable && etl::assignable_from && etl::assignable_from + && etl::assignable_from; + + //*************************************************************************** + template + concept semiregular = etl::copyable && etl::default_initializable; + + //*************************************************************************** + template + concept regular = etl::semiregular && etl::equality_comparable; + + //*************************************************************************** + template + concept predicate = etl::regular_invocable && private_concepts::boolean_testable >; + + //*************************************************************************** + template + concept relation = etl::predicate && etl::predicate && etl::predicate && etl::predicate; + + //*************************************************************************** + template + concept equivalence_relation = etl::relation; + + //*************************************************************************** + template + concept strict_weak_order = etl::relation; + #endif } // namespace etl #endif diff --git a/include/etl/expected.h b/include/etl/expected.h index 2bb2ca9a..829c4247 100644 --- a/include/etl/expected.h +++ b/include/etl/expected.h @@ -604,6 +604,38 @@ namespace etl return etl::move(etl::get(storage)); } + //******************************************* + /// Get the error or a default value. + //******************************************* + template + ETL_NODISCARD ETL_CONSTEXPR14 etl::enable_if_t::value, error_type> error_or(G&& default_error) const& + { + if (has_value()) + { + return static_cast(etl::forward(default_error)); + } + else + { + return error(); + } + } + + //******************************************* + /// Get the error or a default value. + //******************************************* + template + ETL_NODISCARD ETL_CONSTEXPR14 etl::enable_if_t::value, error_type> error_or(G&& default_error) && + { + if (has_value()) + { + return static_cast(etl::forward(default_error)); + } + else + { + return etl::move(error()); + } + } + //******************************************* /// Swap with another etl::expected. //******************************************* @@ -661,6 +693,22 @@ namespace etl { return etl::get(storage); } + + //******************************************* + /// Get the error or a default value. + //******************************************* + template + error_type error_or(const G& default_error) const + { + if (has_value()) + { + return static_cast(default_error); + } + else + { + return error(); + } + } #endif //******************************************* @@ -725,6 +773,39 @@ namespace etl } #endif + //******************************************* + /// Returns a pointer to the value if has_value(), otherwise returns nullptr. + /// Allows expected to be used as a range of 0 or 1 elements. + //******************************************* + ETL_NODISCARD ETL_CONSTEXPR14 value_type* begin() ETL_NOEXCEPT + { + return has_value() ? &etl::get(storage) : ETL_NULLPTR; + } + + //******************************************* + /// Returns a pointer past the value if has_value(), otherwise returns nullptr. + //******************************************* + ETL_NODISCARD ETL_CONSTEXPR14 value_type* end() ETL_NOEXCEPT + { + return has_value() ? &etl::get(storage) + 1 : ETL_NULLPTR; + } + + //******************************************* + /// Returns a const pointer to the value if has_value(), otherwise returns nullptr. + //******************************************* + ETL_NODISCARD ETL_CONSTEXPR14 const value_type* begin() const ETL_NOEXCEPT + { + return has_value() ? &etl::get(storage) : ETL_NULLPTR; + } + + //******************************************* + /// Returns a const pointer past the value if has_value(), otherwise returns nullptr. + //******************************************* + ETL_NODISCARD ETL_CONSTEXPR14 const value_type* end() const ETL_NOEXCEPT + { + return has_value() ? &etl::get(storage) + 1 : ETL_NULLPTR; + } + #if ETL_USING_CPP11 template ::type>::type> auto transform(F&& f) & -> expected @@ -827,13 +908,12 @@ namespace etl enum { - Uninitialised, Value_Type, Error_Type }; - typedef etl::variant storage_type; - storage_type storage; + typedef etl::variant storage_type; + storage_type storage; #if ETL_USING_CPP11 template < typename F, typename TExp, typename TRet, typename TValueRef, typename = typename etl::enable_if::value>::type> @@ -1066,6 +1146,38 @@ namespace etl { return etl::move(etl::get(storage)); } + + //******************************************* + /// Get the error or a default value. + //******************************************* + template + ETL_NODISCARD ETL_CONSTEXPR14 etl::enable_if_t::value, error_type> error_or(G&& default_error) const& + { + if (has_value()) + { + return static_cast(etl::forward(default_error)); + } + else + { + return error(); + } + } + + //******************************************* + /// Get the error or a default value. + //******************************************* + template + ETL_NODISCARD ETL_CONSTEXPR14 etl::enable_if_t::value, error_type> error_or(G&& default_error) && + { + if (has_value()) + { + return static_cast(etl::forward(default_error)); + } + else + { + return etl::move(error()); + } + } #else //******************************************* /// Returns the error @@ -1075,6 +1187,22 @@ namespace etl { return etl::get(storage); } + + //******************************************* + /// Get the error or a default value. + //******************************************* + template + error_type error_or(const G& default_error) const + { + if (has_value()) + { + return static_cast(default_error); + } + else + { + return error(); + } + } #endif //******************************************* @@ -1189,7 +1317,7 @@ namespace etl enum { - Uninitialised, + Void_Type, Error_Type }; @@ -1381,24 +1509,25 @@ namespace etl { return !(lhs == rhs); } + + //******************************************* + /// Swap etl::expected. + //******************************************* + template + ETL_CONSTEXPR14 void swap(etl::expected& lhs, etl::expected& rhs) + { + lhs.swap(rhs); + } + + //******************************************* + /// Swap etl::unexpected. + //******************************************* + template + ETL_CONSTEXPR14 void swap(etl::unexpected& lhs, etl::unexpected& rhs) + { + lhs.swap(rhs); + } + } // namespace etl -//******************************************* -/// Swap etl::expected. -//******************************************* -template -ETL_CONSTEXPR14 void swap(etl::expected& lhs, etl::expected& rhs) -{ - lhs.swap(rhs); -} - -//******************************************* -/// Swap etl::unexpected. -//******************************************* -template -ETL_CONSTEXPR14 void swap(etl::unexpected& lhs, etl::unexpected& rhs) -{ - lhs.swap(rhs); -} - #endif diff --git a/include/etl/memory.h b/include/etl/memory.h index 0bf9e3d6..e4301260 100644 --- a/include/etl/memory.h +++ b/include/etl/memory.h @@ -2370,47 +2370,43 @@ namespace etl pointer p; TDeleter deleter; }; -} // namespace etl -//***************************************************************************** -// Global functions for unique_ptr -//***************************************************************************** -template -bool operator==(const etl::unique_ptr& lhs, const etl::unique_ptr& rhs) -{ - return lhs.get() == rhs.get(); -} + //***************************************************************************** + // Comparison operators for unique_ptr + //***************************************************************************** + template + bool operator==(const etl::unique_ptr& lhs, const etl::unique_ptr& rhs) + { + return lhs.get() == rhs.get(); + } -//********************************* -template -bool operator<(const etl::unique_ptr& lhs, const etl::unique_ptr& rhs) -{ - return reinterpret_cast(lhs.get()) < reinterpret_cast(rhs.get()); -} + //********************************* + template + bool operator<(const etl::unique_ptr& lhs, const etl::unique_ptr& rhs) + { + return reinterpret_cast(lhs.get()) < reinterpret_cast(rhs.get()); + } -//********************************* -template -bool operator<=(const etl::unique_ptr& lhs, const etl::unique_ptr& rhs) -{ - return !(rhs < lhs); -} + //********************************* + template + bool operator<=(const etl::unique_ptr& lhs, const etl::unique_ptr& rhs) + { + return !(rhs < lhs); + } -//********************************* -template -bool operator>(const etl::unique_ptr& lhs, const etl::unique_ptr& rhs) -{ - return (rhs < lhs); -} + //********************************* + template + bool operator>(const etl::unique_ptr& lhs, const etl::unique_ptr& rhs) + { + return (rhs < lhs); + } -//********************************* -template -bool operator>=(const etl::unique_ptr& lhs, const etl::unique_ptr& rhs) -{ - return !(lhs < rhs); -} - -namespace etl -{ + //********************************* + template + bool operator>=(const etl::unique_ptr& lhs, const etl::unique_ptr& rhs) + { + return !(lhs < rhs); + } //***************************************************************************** /// Default construct an item at address p. ///\ingroup memory diff --git a/include/etl/private/bitset_legacy.h b/include/etl/private/bitset_legacy.h index 7fa70ce3..8846e034 100644 --- a/include/etl/private/bitset_legacy.h +++ b/include/etl/private/bitset_legacy.h @@ -1523,16 +1523,16 @@ namespace etl { return !(lhs == rhs); } -} // namespace etl -//************************************************************************* -/// swap -//************************************************************************* -template -void swap(etl::bitset& lhs, etl::bitset& rhs) -{ - lhs.swap(rhs); -} + //************************************************************************* + /// swap + //************************************************************************* + template + void swap(etl::bitset& lhs, etl::bitset& rhs) + { + lhs.swap(rhs); + } +} // namespace etl #include "minmax_pop.h" diff --git a/include/etl/private/bitset_new.h b/include/etl/private/bitset_new.h index 19d21794..e33f3b10 100644 --- a/include/etl/private/bitset_new.h +++ b/include/etl/private/bitset_new.h @@ -2519,32 +2519,30 @@ namespace etl temp ^= rhs; return temp; } -} // namespace etl -//*************************************************************************** -/// operator != -///\ingroup bitset -//*************************************************************************** -template -ETL_CONSTEXPR14 bool operator!=(const etl::bitset& lhs, const etl::bitset& rhs) ETL_NOEXCEPT -{ - return !(lhs == rhs); -} + //*************************************************************************** + /// operator != + ///\ingroup bitset + //*************************************************************************** + template + ETL_CONSTEXPR14 bool operator!=(const etl::bitset& lhs, const etl::bitset& rhs) ETL_NOEXCEPT + { + return !(lhs == rhs); + } -//************************************************************************* -/// swap -//************************************************************************* -template -ETL_CONSTEXPR14 void swap(etl::bitset& lhs, etl::bitset& rhs) ETL_NOEXCEPT -{ - lhs.swap(rhs); -} + //************************************************************************* + /// swap + //************************************************************************* + template + ETL_CONSTEXPR14 void swap(etl::bitset& lhs, etl::bitset& rhs) ETL_NOEXCEPT + { + lhs.swap(rhs); + } + + //*************************************************************************** + /// bitset_ext + //*************************************************************************** -//*************************************************************************** -/// bitset_ext -//*************************************************************************** -namespace etl -{ //*************************************************************************** template class bitset_ext; @@ -3396,29 +3394,26 @@ namespace etl // Pointer to the storage for the bitset. element_type* pbuffer; }; -} // namespace etl -//*************************************************************************** -/// operator != -///\ingroup bitset -//*************************************************************************** -template -ETL_CONSTEXPR14 bool operator!=(const etl::bitset_ext& lhs, const etl::bitset_ext& rhs) ETL_NOEXCEPT -{ - return !(lhs == rhs); -} + //*************************************************************************** + /// operator != + ///\ingroup bitset + //*************************************************************************** + template + ETL_CONSTEXPR14 bool operator!=(const etl::bitset_ext& lhs, const etl::bitset_ext& rhs) ETL_NOEXCEPT + { + return !(lhs == rhs); + } -//************************************************************************* -/// swap -//************************************************************************* -template -ETL_CONSTEXPR14 void swap(etl::bitset_ext& lhs, etl::bitset_ext& rhs) ETL_NOEXCEPT -{ - lhs.swap(rhs); -} + //************************************************************************* + /// swap + //************************************************************************* + template + ETL_CONSTEXPR14 void swap(etl::bitset_ext& lhs, etl::bitset_ext& rhs) ETL_NOEXCEPT + { + lhs.swap(rhs); + } -namespace etl -{ namespace private_bitset { //************************************************************************* @@ -3464,216 +3459,217 @@ namespace etl return true; } } // namespace private_bitset + + //*************************************************************************** + /// operator == + /// bitset + /// Different element types + ///\ingroup bitset + //*************************************************************************** + template + ETL_CONSTEXPR14 typename etl::enable_if::value, bool>::type + operator==(const etl::bitset& lhs, const etl::bitset& rhs) ETL_NOEXCEPT + { + // Get a span of each type. + typename etl::bitset::const_span_type lhs_span = lhs.span(); + typename etl::bitset::const_span_type rhs_span = rhs.span(); + + // Put the bitset with the largest element type as the first argument. + if ETL_IF_CONSTEXPR (sizeof(TLhsElement) > sizeof(TRhsElement)) + { + return etl::private_bitset::compare_bitset_spans(lhs_span, rhs_span); + } + else + { + return etl::private_bitset::compare_bitset_spans(rhs_span, lhs_span); + } + } + + //*************************************************************************** + /// operator != + /// bitset + /// Different element types + ///\ingroup bitset + //*************************************************************************** + template + ETL_CONSTEXPR14 typename etl::enable_if::value, bool>::type + operator!=(const etl::bitset& lhs, const etl::bitset& rhs) ETL_NOEXCEPT + { + return !(lhs == rhs); + } + + //*************************************************************************** + /// operator == + /// bitset_ext + /// Different element types + ///\ingroup bitset + //*************************************************************************** + template + ETL_CONSTEXPR14 typename etl::enable_if::value, bool>::type + operator==(const etl::bitset_ext& lhs, const etl::bitset_ext& rhs) ETL_NOEXCEPT + { + // Get a span of each type. + typename etl::bitset_ext::const_span_type lhs_span = lhs.span(); + typename etl::bitset_ext::const_span_type rhs_span = rhs.span(); + + // Put the bitset with the largest element type as the first argument. + if ETL_IF_CONSTEXPR (sizeof(TLhsElement) > sizeof(TRhsElement)) + { + return etl::private_bitset::compare_bitset_spans(lhs_span, rhs_span); + } + else + { + return etl::private_bitset::compare_bitset_spans(rhs_span, lhs_span); + } + } + + //*************************************************************************** + /// operator != + /// bitset_ext + /// Different element types + ///\ingroup bitset + //*************************************************************************** + template + ETL_CONSTEXPR14 typename etl::enable_if::value, bool>::type + operator!=(const etl::bitset_ext& lhs, const etl::bitset_ext& rhs) ETL_NOEXCEPT + { + return !(lhs == rhs); + } + + //*************************************************************************** + /// operator == + /// bitset compared with bitset_ext, same element types. + ///\ingroup bitset + //*************************************************************************** + template + ETL_CONSTEXPR14 bool operator==(const etl::bitset& lhs, const etl::bitset_ext& rhs) ETL_NOEXCEPT + { + const char Storage_Model = etl::bitset::Storage_Model; + const size_t Number_Of_Elements = etl::bitset::Number_Of_Elements; + + typename etl::bitset::const_span_type lhs_span = lhs.span(); + typename etl::bitset_ext::const_span_type rhs_span = rhs.span(); + + typedef etl::bitset_impl implementation; + + return implementation::operator_equality(lhs_span.begin(), rhs_span.begin(), Number_Of_Elements); + } + + //*************************************************************************** + /// operator != + /// bitset compared with bitset_ext, same element types. + ///\ingroup bitset + //*************************************************************************** + template + ETL_CONSTEXPR14 bool operator!=(const etl::bitset& lhs, const etl::bitset_ext& rhs) ETL_NOEXCEPT + { + return !(lhs == rhs); + } + + //*************************************************************************** + /// operator == + /// bitset_ext compared with bitset, same element types. + ///\ingroup bitset + //*************************************************************************** + template + ETL_CONSTEXPR14 bool operator==(const etl::bitset_ext& lhs, const etl::bitset& rhs) ETL_NOEXCEPT + { + const char Storage_Model = etl::bitset::Storage_Model; + const size_t Number_Of_Elements = etl::bitset::Number_Of_Elements; + + typename etl::bitset_ext::const_span_type lhs_span = lhs.span(); + typename etl::bitset::const_span_type rhs_span = rhs.span(); + + typedef etl::bitset_impl implementation; + + return implementation::operator_equality(lhs_span.begin(), rhs_span.begin(), Number_Of_Elements); + } + + //*************************************************************************** + /// operator != + /// bitset_ext compared with bitset, same element types. + ///\ingroup bitset + //*************************************************************************** + template + ETL_CONSTEXPR14 bool operator!=(const etl::bitset_ext& lhs, const etl::bitset& rhs) ETL_NOEXCEPT + { + return !(lhs == rhs); + } + + //*************************************************************************** + /// operator == + /// bitset compared with bitset_ext, different element types. + ///\ingroup bitset + //*************************************************************************** + template + ETL_CONSTEXPR14 typename etl::enable_if::value, bool>::type + operator==(const etl::bitset& lhs, const etl::bitset_ext& rhs) ETL_NOEXCEPT + { + // Get a span of each type. + typename etl::bitset::const_span_type lhs_span = lhs.span(); + typename etl::bitset_ext::const_span_type rhs_span = rhs.span(); + + // Put the bitset with the largest element type as the first argument. + if ETL_IF_CONSTEXPR (sizeof(TLhsElement) > sizeof(TRhsElement)) + { + return etl::private_bitset::compare_bitset_spans(lhs_span, rhs_span); + } + else + { + return etl::private_bitset::compare_bitset_spans(rhs_span, lhs_span); + } + } + + //*************************************************************************** + /// operator != + /// bitset compared with bitset_ext, different element types. + ///\ingroup bitset + //*************************************************************************** + template + ETL_CONSTEXPR14 typename etl::enable_if::value, bool>::type + operator!=(const etl::bitset& lhs, const etl::bitset_ext& rhs) ETL_NOEXCEPT + { + return !(lhs == rhs); + } + + //*************************************************************************** + /// operator == + /// bitset_ext compared with bitset, different element types. + ///\ingroup bitset + //*************************************************************************** + template + ETL_CONSTEXPR14 typename etl::enable_if::value, bool>::type + operator==(const etl::bitset_ext& lhs, const etl::bitset& rhs) ETL_NOEXCEPT + { + // Get a span of each type. + typename etl::bitset_ext::const_span_type lhs_span = lhs.span(); + typename etl::bitset::const_span_type rhs_span = rhs.span(); + + // Put the bitset with the largest element type as the first argument. + if ETL_IF_CONSTEXPR (sizeof(TLhsElement) > sizeof(TRhsElement)) + { + return etl::private_bitset::compare_bitset_spans(lhs_span, rhs_span); + } + else + { + return etl::private_bitset::compare_bitset_spans(rhs_span, lhs_span); + } + } + + //*************************************************************************** + /// operator != + /// bitset_ext compared with bitset, different element types. + ///\ingroup bitset + //*************************************************************************** + template + ETL_CONSTEXPR14 typename etl::enable_if::value, bool>::type + operator!=(const etl::bitset_ext& lhs, const etl::bitset& rhs) ETL_NOEXCEPT + { + return !(lhs == rhs); + } + } // namespace etl -//*************************************************************************** -/// operator == -/// bitset -/// Different element types -///\ingroup bitset -//*************************************************************************** -template -ETL_CONSTEXPR14 typename etl::enable_if::value, bool>::type - operator==(const etl::bitset& lhs, const etl::bitset& rhs) ETL_NOEXCEPT -{ - // Get a span of each type. - typename etl::bitset::const_span_type lhs_span = lhs.span(); - typename etl::bitset::const_span_type rhs_span = rhs.span(); - - // Put the bitset with the largest element type as the first argument. - if ETL_IF_CONSTEXPR (sizeof(TLhsElement) > sizeof(TRhsElement)) - { - return etl::private_bitset::compare_bitset_spans(lhs_span, rhs_span); - } - else - { - return etl::private_bitset::compare_bitset_spans(rhs_span, lhs_span); - } -} - -//*************************************************************************** -/// operator != -/// bitset -/// Different element types -///\ingroup bitset -//*************************************************************************** -template -ETL_CONSTEXPR14 typename etl::enable_if::value, bool>::type - operator!=(const etl::bitset& lhs, const etl::bitset& rhs) ETL_NOEXCEPT -{ - return !(lhs == rhs); -} - -//*************************************************************************** -/// operator == -/// bitset_ext -/// Different element types -///\ingroup bitset -//*************************************************************************** -template -ETL_CONSTEXPR14 typename etl::enable_if::value, bool>::type - operator==(const etl::bitset_ext& lhs, const etl::bitset_ext& rhs) ETL_NOEXCEPT -{ - // Get a span of each type. - typename etl::bitset_ext::const_span_type lhs_span = lhs.span(); - typename etl::bitset_ext::const_span_type rhs_span = rhs.span(); - - // Put the bitset with the largest element type as the first argument. - if ETL_IF_CONSTEXPR (sizeof(TLhsElement) > sizeof(TRhsElement)) - { - return etl::private_bitset::compare_bitset_spans(lhs_span, rhs_span); - } - else - { - return etl::private_bitset::compare_bitset_spans(rhs_span, lhs_span); - } -} - -//*************************************************************************** -/// operator != -/// bitset_ext -/// Different element types -///\ingroup bitset -//*************************************************************************** -template -ETL_CONSTEXPR14 typename etl::enable_if::value, bool>::type - operator!=(const etl::bitset_ext& lhs, const etl::bitset_ext& rhs) ETL_NOEXCEPT -{ - return !(lhs == rhs); -} - -//*************************************************************************** -/// operator == -/// bitset compared with bitset_ext, same element types. -///\ingroup bitset -//*************************************************************************** -template -ETL_CONSTEXPR14 bool operator==(const etl::bitset& lhs, const etl::bitset_ext& rhs) ETL_NOEXCEPT -{ - const char Storage_Model = etl::bitset::Storage_Model; - const size_t Number_Of_Elements = etl::bitset::Number_Of_Elements; - - typename etl::bitset::const_span_type lhs_span = lhs.span(); - typename etl::bitset_ext::const_span_type rhs_span = rhs.span(); - - typedef etl::bitset_impl implementation; - - return implementation::operator_equality(lhs_span.begin(), rhs_span.begin(), Number_Of_Elements); -} - -//*************************************************************************** -/// operator != -/// bitset compared with bitset_ext, same element types. -///\ingroup bitset -//*************************************************************************** -template -ETL_CONSTEXPR14 bool operator!=(const etl::bitset& lhs, const etl::bitset_ext& rhs) ETL_NOEXCEPT -{ - return !(lhs == rhs); -} - -//*************************************************************************** -/// operator == -/// bitset_ext compared with bitset, same element types. -///\ingroup bitset -//*************************************************************************** -template -ETL_CONSTEXPR14 bool operator==(const etl::bitset_ext& lhs, const etl::bitset& rhs) ETL_NOEXCEPT -{ - const char Storage_Model = etl::bitset::Storage_Model; - const size_t Number_Of_Elements = etl::bitset::Number_Of_Elements; - - typename etl::bitset_ext::const_span_type lhs_span = lhs.span(); - typename etl::bitset::const_span_type rhs_span = rhs.span(); - - typedef etl::bitset_impl implementation; - - return implementation::operator_equality(lhs_span.begin(), rhs_span.begin(), Number_Of_Elements); -} - -//*************************************************************************** -/// operator != -/// bitset_ext compared with bitset, same element types. -///\ingroup bitset -//*************************************************************************** -template -ETL_CONSTEXPR14 bool operator!=(const etl::bitset_ext& lhs, const etl::bitset& rhs) ETL_NOEXCEPT -{ - return !(lhs == rhs); -} - -//*************************************************************************** -/// operator == -/// bitset compared with bitset_ext, different element types. -///\ingroup bitset -//*************************************************************************** -template -ETL_CONSTEXPR14 typename etl::enable_if::value, bool>::type - operator==(const etl::bitset& lhs, const etl::bitset_ext& rhs) ETL_NOEXCEPT -{ - // Get a span of each type. - typename etl::bitset::const_span_type lhs_span = lhs.span(); - typename etl::bitset_ext::const_span_type rhs_span = rhs.span(); - - // Put the bitset with the largest element type as the first argument. - if ETL_IF_CONSTEXPR (sizeof(TLhsElement) > sizeof(TRhsElement)) - { - return etl::private_bitset::compare_bitset_spans(lhs_span, rhs_span); - } - else - { - return etl::private_bitset::compare_bitset_spans(rhs_span, lhs_span); - } -} - -//*************************************************************************** -/// operator != -/// bitset compared with bitset_ext, different element types. -///\ingroup bitset -//*************************************************************************** -template -ETL_CONSTEXPR14 typename etl::enable_if::value, bool>::type - operator!=(const etl::bitset& lhs, const etl::bitset_ext& rhs) ETL_NOEXCEPT -{ - return !(lhs == rhs); -} - -//*************************************************************************** -/// operator == -/// bitset_ext compared with bitset, different element types. -///\ingroup bitset -//*************************************************************************** -template -ETL_CONSTEXPR14 typename etl::enable_if::value, bool>::type - operator==(const etl::bitset_ext& lhs, const etl::bitset& rhs) ETL_NOEXCEPT -{ - // Get a span of each type. - typename etl::bitset_ext::const_span_type lhs_span = lhs.span(); - typename etl::bitset::const_span_type rhs_span = rhs.span(); - - // Put the bitset with the largest element type as the first argument. - if ETL_IF_CONSTEXPR (sizeof(TLhsElement) > sizeof(TRhsElement)) - { - return etl::private_bitset::compare_bitset_spans(lhs_span, rhs_span); - } - else - { - return etl::private_bitset::compare_bitset_spans(rhs_span, lhs_span); - } -} - -//*************************************************************************** -/// operator != -/// bitset_ext compared with bitset, different element types. -///\ingroup bitset -//*************************************************************************** -template -ETL_CONSTEXPR14 typename etl::enable_if::value, bool>::type - operator!=(const etl::bitset_ext& lhs, const etl::bitset& rhs) ETL_NOEXCEPT -{ - return !(lhs == rhs); -} - #include "minmax_pop.h" #endif diff --git a/include/etl/tuple.h b/include/etl/tuple.h index f76c0a62..0a419374 100644 --- a/include/etl/tuple.h +++ b/include/etl/tuple.h @@ -35,6 +35,7 @@ SOFTWARE. #if ETL_USING_STL #include + #include #endif #include "functional.h" @@ -1179,7 +1180,9 @@ namespace etl namespace std { - #if ETL_NOT_USING_STL && !((defined(ETL_DEVELOPMENT_OS_APPLE) || (ETL_COMPILER_FULL_VERSION >= 190000)) && defined(ETL_COMPILER_CLANG)) + #if ETL_NOT_USING_STL \ + && !((defined(ETL_DEVELOPMENT_OS_APPLE) || (ETL_COMPILER_FULL_VERSION >= 190000) && (ETL_COMPILER_FULL_VERSION < 220000)) \ + && defined(ETL_COMPILER_CLANG)) template struct tuple_size; diff --git a/include/etl/type_traits.h b/include/etl/type_traits.h index 2600da96..2b4372af 100644 --- a/include/etl/type_traits.h +++ b/include/etl/type_traits.h @@ -649,6 +649,18 @@ namespace etl struct is_void : true_type { }; + template <> + struct is_void : true_type + { + }; + template <> + struct is_void : true_type + { + }; + template <> + struct is_void : true_type + { + }; #if ETL_USING_CPP17 template @@ -3977,6 +3989,19 @@ namespace etl template inline constexpr bool is_function_v = etl::is_function::value; #endif + + //*************************************************************************** + /// is_object + //*************************************************************************** + template + struct is_object : etl::bool_constant::value && !etl::is_reference::value && !etl::is_void::value> + { + }; + + #if ETL_USING_CPP17 + template + inline constexpr bool is_object_v = etl::is_object::value; + #endif #endif #if ETL_USING_CPP11 diff --git a/test/test_concepts.cpp b/test/test_concepts.cpp index 347ec8fb..a6b03830 100644 --- a/test/test_concepts.cpp +++ b/test/test_concepts.cpp @@ -29,6 +29,7 @@ SOFTWARE. #include "unit_test_framework.h" #include +#include #include #if ETL_USING_CPP20 @@ -52,6 +53,65 @@ namespace { }; + struct NotDestructible + { + ~NotDestructible() = delete; + }; + + struct NotDefaultConstructible + { + NotDefaultConstructible(int) {} + }; + + struct NotCopyable + { + NotCopyable() = default; + NotCopyable(const NotCopyable&) = delete; + NotCopyable(NotCopyable&&) = default; + NotCopyable& operator=(const NotCopyable&) = delete; + NotCopyable& operator=(NotCopyable&&) = default; + }; + + struct NotMovable + { + NotMovable() = default; + NotMovable(const NotMovable&) = delete; + NotMovable(NotMovable&&) = delete; + NotMovable& operator=(const NotMovable&) = delete; + NotMovable& operator=(NotMovable&&) = delete; + }; + + struct NotEqualityComparable + { + }; + + struct EqualityComparableType + { + bool operator==(const EqualityComparableType&) const = default; + }; + + struct OrderedType + { + int value; + auto operator<=>(const OrderedType&) const = default; + }; + + struct BoolPredicate + { + bool operator()(int) const + { + return true; + } + }; + + struct IntRelation + { + bool operator()(int, int) const + { + return true; + } + }; + SUITE(test_concepts) { //************************************************************************* @@ -140,6 +200,183 @@ namespace static_assert(etl::assignable_from == false); static_assert(etl::assignable_from&, int> == false); } + + //************************************************************************* + TEST(test_invocable) + { + struct Functor + { + void operator()() {} + }; + struct FunctorWithArgs + { + int operator()(int, double) + { + return 0; + } + }; + + static_assert(etl::invocable == true); + static_assert(etl::invocable == true); + static_assert(etl::invocable == true); + static_assert(etl::invocable == true); + static_assert(etl::invocable == false); + static_assert(etl::invocable == false); + } + + //************************************************************************* + TEST(test_regular_invocable) + { + struct Functor + { + void operator()() {} + }; + + static_assert(etl::regular_invocable == true); + static_assert(etl::regular_invocable == true); + static_assert(etl::regular_invocable == false); + } + + //************************************************************************* + TEST(test_destructible) + { + static_assert(etl::destructible == true); + static_assert(etl::destructible == true); + static_assert(etl::destructible == false); + } + + //************************************************************************* + TEST(test_constructible_from) + { + static_assert(etl::constructible_from == true); + static_assert(etl::constructible_from == true); + static_assert(etl::constructible_from == true); + static_assert(etl::constructible_from == false); + } + + //************************************************************************* + TEST(test_default_initializable) + { + static_assert(etl::default_initializable == true); + static_assert(etl::default_initializable == true); + static_assert(etl::default_initializable == false); + } + + //************************************************************************* + TEST(test_move_constructible) + { + static_assert(etl::move_constructible == true); + static_assert(etl::move_constructible == true); + static_assert(etl::move_constructible == false); + } + + //************************************************************************* + TEST(test_copy_constructible) + { + static_assert(etl::copy_constructible == true); + static_assert(etl::copy_constructible == true); + static_assert(etl::copy_constructible == false); + } + + //************************************************************************* + TEST(test_equality_comparable) + { + static_assert(etl::equality_comparable == true); + static_assert(etl::equality_comparable == true); + static_assert(etl::equality_comparable == false); + } + + //************************************************************************* + TEST(test_totally_ordered) + { + static_assert(etl::totally_ordered == true); + static_assert(etl::totally_ordered == true); + static_assert(etl::totally_ordered == false); + } + + //************************************************************************* + TEST(test_swappable) + { + static_assert(etl::swappable == true); + static_assert(etl::swappable == true); + static_assert(etl::swappable == false); + } + + //************************************************************************* + TEST(test_swappable_with) + { + // Positive cases: same-type lvalue references that are swappable + static_assert(etl::swappable_with == true); + static_assert(etl::swappable_with == true); + + // Negative cases: unrelated types (no valid swap overload) + static_assert(etl::swappable_with == false); + + // Negative case: non-movable type cannot be swapped + static_assert(etl::swappable_with == false); + } + + //************************************************************************* + TEST(test_movable) + { + static_assert(etl::movable == true); + static_assert(etl::movable == true); + static_assert(etl::movable == false); + } + + //************************************************************************* + TEST(test_copyable) + { + static_assert(etl::copyable == true); + static_assert(etl::copyable == true); + static_assert(etl::copyable == false); + } + + //************************************************************************* + TEST(test_semiregular) + { + static_assert(etl::semiregular == true); + static_assert(etl::semiregular == true); + static_assert(etl::semiregular == false); + } + + //************************************************************************* + TEST(test_regular) + { + static_assert(etl::regular == true); + static_assert(etl::regular == true); + static_assert(etl::regular == false); + } + + //************************************************************************* + TEST(test_predicate) + { + static_assert(etl::predicate == true); + static_assert(etl::predicate == true); + static_assert(etl::predicate == false); + } + + //************************************************************************* + TEST(test_relation) + { + static_assert(etl::relation == true); + static_assert(etl::relation, int, int> == true); + static_assert(etl::relation == false); + } + + //************************************************************************* + TEST(test_equivalence_relation) + { + static_assert(etl::equivalence_relation, int, int> == true); + static_assert(etl::equivalence_relation == false); + } + + //************************************************************************* + TEST(test_strict_weak_order) + { + static_assert(etl::strict_weak_order, int, int> == true); + static_assert(etl::strict_weak_order == false); + } } } // namespace #endif diff --git a/test/test_expected.cpp b/test/test_expected.cpp index 024ecf47..a28e2f54 100644 --- a/test/test_expected.cpp +++ b/test/test_expected.cpp @@ -31,6 +31,7 @@ SOFTWARE. #include "etl/expected.h" #include "etl/type_traits.h" +#include #include #include @@ -1477,5 +1478,143 @@ namespace auto with_error_type_check = check_expected_type_helper(unexpected_out); CHECK_TRUE(with_error_type_check); } + + //************************************************************************* + TEST(test_begin_end_with_value) + { + etl::expected exp(std::string("hello")); + + CHECK_TRUE(exp.begin() != exp.end()); + CHECK_EQUAL(std::distance(exp.begin(), exp.end()), 1); + CHECK_EQUAL(*exp.begin(), std::string("hello")); + } + + //************************************************************************* + TEST(test_begin_end_with_error) + { + etl::expected exp(etl::unexpected(Error("err"))); + + CHECK_TRUE(exp.begin() == exp.end()); + CHECK_EQUAL(std::distance(exp.begin(), exp.end()), 0); + } + + //************************************************************************* + TEST(test_begin_end_const_with_value) + { + const etl::expected exp(std::string("world")); + + CHECK_TRUE(exp.begin() != exp.end()); + CHECK_EQUAL(std::distance(exp.begin(), exp.end()), 1); + CHECK_EQUAL(*exp.begin(), std::string("world")); + } + + //************************************************************************* + TEST(test_begin_end_const_with_error) + { + const etl::expected exp(etl::unexpected(Error("err"))); + + CHECK_TRUE(exp.begin() == exp.end()); + CHECK_EQUAL(std::distance(exp.begin(), exp.end()), 0); + } + + //************************************************************************* + TEST(test_range_for_with_value) + { + etl::expected exp(42); + + int count = 0; + int sum = 0; + for (auto& v : exp) + { + ++count; + sum += v; + } + + CHECK_EQUAL(1, count); + CHECK_EQUAL(42, sum); + } + + //************************************************************************* + TEST(test_range_for_with_error) + { + etl::expected exp(etl::unexpected(Error("err"))); + + int count = 0; + for (auto& v : exp) + { + (void)v; + ++count; + } + + CHECK_EQUAL(0, count); + } + + //************************************************************************* + TEST(test_error_or_with_value) + { + etl::expected exp(42); + + Error result = exp.error_or(Error("default")); + CHECK_EQUAL("default", result.e); + } + + //************************************************************************* + TEST(test_error_or_with_error) + { + etl::expected exp(etl::unexpected(Error("real_error"))); + + Error result = exp.error_or(Error("default")); + CHECK_EQUAL("real_error", result.e); + } + + //************************************************************************* + TEST(test_error_or_const_with_value) + { + const etl::expected exp(42); + + Error result = exp.error_or(Error("default")); + CHECK_EQUAL("default", result.e); + } + + //************************************************************************* + TEST(test_error_or_const_with_error) + { + const etl::expected exp(etl::unexpected(Error("real_error"))); + + Error result = exp.error_or(Error("default")); + CHECK_EQUAL("real_error", result.e); + } + + //************************************************************************* + TEST(test_error_or_rvalue_with_value) + { + Error result = etl::expected(42).error_or(Error("default")); + CHECK_EQUAL("default", result.e); + } + + //************************************************************************* + TEST(test_error_or_rvalue_with_error) + { + Error result = etl::expected(etl::unexpected(Error("real_error"))).error_or(Error("default")); + CHECK_EQUAL("real_error", result.e); + } + + //************************************************************************* + TEST(test_error_or_void_value_with_value) + { + etl::expected exp; + + Error result = exp.error_or(Error("default")); + CHECK_EQUAL("default", result.e); + } + + //************************************************************************* + TEST(test_error_or_void_value_with_error) + { + etl::expected exp(etl::unexpected(Error("real_error"))); + + Error result = exp.error_or(Error("default")); + CHECK_EQUAL("real_error", result.e); + } } } // namespace diff --git a/test/test_type_traits.cpp b/test/test_type_traits.cpp index f6ef4cda..bb4d73f1 100644 --- a/test/test_type_traits.cpp +++ b/test/test_type_traits.cpp @@ -2211,5 +2211,43 @@ namespace CHECK_FALSE((etl::is_function::value)); CHECK_FALSE((etl::is_function::value)); // pointer, not function } + + //************************************************************************* + TEST(test_is_object) + { + CHECK_TRUE((etl::is_object::value)); + CHECK_TRUE((etl::is_object::value)); + CHECK_TRUE((etl::is_object::value)); + CHECK_TRUE((etl::is_object::value)); + CHECK_TRUE((etl::is_object::value)); + CHECK_TRUE((etl::is_object::value)); + CHECK_TRUE((etl::is_object::value)); + + CHECK_FALSE((etl::is_object::value)); + CHECK_FALSE((etl::is_object::value)); + CHECK_FALSE((etl::is_object::value)); + CHECK_FALSE((etl::is_object::value)); + CHECK_FALSE((etl::is_object::value)); + CHECK_FALSE((etl::is_object::value)); + CHECK_FALSE((etl::is_object::value)); + + CHECK_TRUE((etl::is_void::value)); + CHECK_TRUE((etl::is_void::value)); + CHECK_TRUE((etl::is_void::value)); + +#if ETL_USING_CPP17 + CHECK_TRUE((etl::is_object_v)); + CHECK_TRUE((etl::is_object_v)); + CHECK_TRUE((etl::is_object_v)); + + CHECK_FALSE((etl::is_object_v)); + CHECK_FALSE((etl::is_object_v)); + CHECK_FALSE((etl::is_object_v)); + CHECK_FALSE((etl::is_object_v)); + CHECK_FALSE((etl::is_object_v)); + CHECK_FALSE((etl::is_object_v)); + CHECK_FALSE((etl::is_object_v)); +#endif + } } } // namespace