aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/include/newtype/newtype.hpp196
1 files changed, 64 insertions, 132 deletions
diff --git a/lib/include/newtype/newtype.hpp b/lib/include/newtype/newtype.hpp
index fecaf2c..5a9b8ff 100644
--- a/lib/include/newtype/newtype.hpp
+++ b/lib/include/newtype/newtype.hpp
@@ -1,11 +1,17 @@
#ifndef NEWTYPE_NEWTYPE_HPP
#define NEWTYPE_NEWTYPE_HPP
+#if __has_include(<istream>) && __has_include(<ostream>)
+#define HAS_I_O_STREAM
+#endif
+
#include <algorithm>
#include <compare>
#include <functional>
+#ifdef HAS_I_O_STREAM
#include <istream>
#include <ostream>
+#endif
#include <type_traits>
#include <utility>
@@ -87,16 +93,12 @@ namespace nt
#define NEWTYPE_MAKE_ARITHMETIC_CONCEPT(NAME, OPERATOR, REF) \
template<typename SubjectType> \
concept NAME = requires(SubjectType lhs, SubjectType rhs) { \
- { \
- lhs OPERATOR rhs \
- } -> std::same_as<SubjectType REF>; \
+ { lhs OPERATOR rhs } -> std::same_as<SubjectType REF>; \
}; \
template<typename SubjectType> \
concept nothrow_##NAME = requires(SubjectType lhs, SubjectType rhs) { \
requires NAME<SubjectType>; \
- { \
- lhs OPERATOR rhs \
- } noexcept; \
+ { lhs OPERATOR rhs } noexcept; \
};
NEWTYPE_MAKE_ARITHMETIC_CONCEPT(addable, +, /*no-ref*/)
@@ -116,103 +118,78 @@ namespace nt
template<typename SubjectType>
concept nothrow_three_way_comparable = requires(SubjectType lhs, SubjectType rhs) {
requires std::three_way_comparable<SubjectType>;
- {
- lhs <=> rhs
- } noexcept;
+ { lhs <=> rhs } noexcept;
};
template<typename SubjectType>
concept equality_comparable = requires(SubjectType lhs, SubjectType rhs) {
- {
- lhs == rhs
- } -> std::convertible_to<bool>;
+ { lhs == rhs } -> std::convertible_to<bool>;
};
template<typename SubjectType>
concept nothrow_equality_comparable = requires(SubjectType lhs, SubjectType rhs) {
requires equality_comparable<SubjectType>;
- {
- lhs == rhs
- } noexcept;
+ { lhs == rhs } noexcept;
};
template<typename SubjectType>
concept inequality_comparable = requires(SubjectType lhs, SubjectType rhs) {
- {
- lhs != rhs
- } -> std::convertible_to<bool>;
+ { lhs != rhs } -> std::convertible_to<bool>;
};
template<typename SubjectType>
concept nothrow_inequality_comparable = requires(SubjectType lhs, SubjectType rhs) {
requires inequality_comparable<SubjectType>;
- {
- lhs != rhs
- } noexcept;
+ { lhs != rhs } noexcept;
};
template<typename SubjectType>
concept less_than_comparable = requires(SubjectType lhs, SubjectType rhs) {
- {
- lhs < rhs
- } -> std::convertible_to<bool>;
+ { lhs < rhs } -> std::convertible_to<bool>;
};
template<typename SubjectType>
concept nothrow_less_than_comparable = requires(SubjectType lhs, SubjectType rhs) {
requires less_than_comparable<SubjectType>;
- {
- lhs < rhs
- } noexcept;
+ { lhs < rhs } noexcept;
};
template<typename SubjectType>
concept less_than_equal_comparable = requires(SubjectType lhs, SubjectType rhs) {
- {
- lhs <= rhs
- } -> std::convertible_to<bool>;
+ { lhs <= rhs } -> std::convertible_to<bool>;
};
template<typename SubjectType>
concept nothrow_less_than_equal_comparable = requires(SubjectType lhs, SubjectType rhs) {
requires less_than_equal_comparable<SubjectType>;
- {
- lhs <= rhs
- } noexcept;
+ { lhs <= rhs } noexcept;
};
template<typename SubjectType>
concept greater_than_comparable = requires(SubjectType lhs, SubjectType rhs) {
- {
- lhs > rhs
- } -> std::convertible_to<bool>;
+ { lhs > rhs } -> std::convertible_to<bool>;
};
template<typename SubjectType>
concept nothrow_greater_than_comparable = requires(SubjectType lhs, SubjectType rhs) {
requires greater_than_comparable<SubjectType>;
- {
- lhs > rhs
- } noexcept;
+ { lhs > rhs } noexcept;
};
template<typename SubjectType>
concept greater_than_equal_comparable = requires(SubjectType lhs, SubjectType rhs) {
- {
- lhs >= rhs
- } -> std::convertible_to<bool>;
+ { lhs >= rhs } -> std::convertible_to<bool>;
};
template<typename SubjectType>
concept nothrow_greater_than_equal_comparable = requires(SubjectType lhs, SubjectType rhs) {
requires greater_than_equal_comparable<SubjectType>;
- {
- lhs >= rhs
- } noexcept;
+ { lhs >= rhs } noexcept;
};
} // namespace comparability
+#ifdef HAS_I_O_STREAM
inline namespace iostreamable
{
@@ -226,9 +203,7 @@ namespace nt
template<typename SubjectType, typename CharType, typename StreamTraits>
concept nothrow_input_streamable = requires(SubjectType subject) {
requires input_streamable<SubjectType, CharType, StreamTraits>;
- {
- std::declval<std::basic_istream<CharType, StreamTraits> &>() >> subject
- } noexcept;
+ { std::declval<std::basic_istream<CharType, StreamTraits> &>() >> subject } noexcept;
};
template<typename SubjectType, typename CharType, typename StreamTraits>
@@ -241,12 +216,11 @@ namespace nt
template<typename SubjectType, typename CharType, typename StreamTraits>
concept nothrow_output_streamable = requires(SubjectType subject) {
requires output_streamable<SubjectType, CharType, StreamTraits>;
- {
- std::declval<std::basic_ostream<CharType, StreamTraits> &>() << subject
- } noexcept;
+ { std::declval<std::basic_ostream<CharType, StreamTraits> &>() << subject } noexcept;
};
} // namespace iostreamable
+#endif
inline namespace iterable
{
@@ -254,33 +228,25 @@ namespace nt
template<typename SubjectType>
concept free_begin = requires(SubjectType & subject) {
typename SubjectType::iterator;
- {
- begin(subject)
- } -> std::same_as<typename SubjectType::iterator>;
+ { begin(subject) } -> std::same_as<typename SubjectType::iterator>;
};
template<typename SubjectType>
concept const_free_begin = requires(SubjectType const & subject) {
typename SubjectType::const_iterator;
- {
- begin(subject)
- } -> std::same_as<typename SubjectType::const_iterator>;
+ { begin(subject) } -> std::same_as<typename SubjectType::const_iterator>;
};
template<typename SubjectType>
concept member_begin = requires(SubjectType & subject) {
typename SubjectType::iterator;
- {
- subject.begin()
- } -> std::same_as<typename SubjectType::iterator>;
+ { subject.begin() } -> std::same_as<typename SubjectType::iterator>;
};
template<typename SubjectType>
concept const_member_begin = requires(SubjectType const & subject) {
typename SubjectType::const_iterator;
- {
- subject.begin()
- } -> std::same_as<typename SubjectType::const_iterator>;
+ { subject.begin() } -> std::same_as<typename SubjectType::const_iterator>;
};
template<typename SubjectType>
@@ -292,17 +258,13 @@ namespace nt
template<typename SubjectType>
concept free_cbegin = requires(SubjectType const & subject) {
typename SubjectType::const_iterator;
- {
- cbegin(subject)
- } -> std::same_as<typename SubjectType::const_iterator>;
+ { cbegin(subject) } -> std::same_as<typename SubjectType::const_iterator>;
};
template<typename SubjectType>
concept member_cbegin = requires(SubjectType const & subject) {
typename SubjectType::const_iterator;
- {
- subject.cbegin()
- } -> std::same_as<typename SubjectType::const_iterator>;
+ { subject.cbegin() } -> std::same_as<typename SubjectType::const_iterator>;
};
template<typename SubjectType>
@@ -311,33 +273,25 @@ namespace nt
template<typename SubjectType>
concept free_rbegin = requires(SubjectType & subject) {
typename SubjectType::reverse_iterator;
- {
- rbegin(subject)
- } -> std::same_as<typename SubjectType::reverse_iterator>;
+ { rbegin(subject) } -> std::same_as<typename SubjectType::reverse_iterator>;
};
template<typename SubjectType>
concept const_free_rbegin = requires(SubjectType const & subject) {
typename SubjectType::const_reverse_iterator;
- {
- rbegin(subject)
- } -> std::same_as<typename SubjectType::const_reverse_iterator>;
+ { rbegin(subject) } -> std::same_as<typename SubjectType::const_reverse_iterator>;
};
template<typename SubjectType>
concept member_rbegin = requires(SubjectType & subject) {
typename SubjectType::reverse_iterator;
- {
- subject.rbegin()
- } -> std::same_as<typename SubjectType::reverse_iterator>;
+ { subject.rbegin() } -> std::same_as<typename SubjectType::reverse_iterator>;
};
template<typename SubjectType>
concept const_member_rbegin = requires(SubjectType const & subject) {
typename SubjectType::const_reverse_iterator;
- {
- subject.rbegin()
- } -> std::same_as<typename SubjectType::const_reverse_iterator>;
+ { subject.rbegin() } -> std::same_as<typename SubjectType::const_reverse_iterator>;
};
template<typename SubjectType>
@@ -349,17 +303,13 @@ namespace nt
template<typename SubjectType>
concept free_crbegin = requires(SubjectType const & subject) {
typename SubjectType::const_reverse_iterator;
- {
- crbegin(subject)
- } -> std::same_as<typename SubjectType::const_reverse_iterator>;
+ { crbegin(subject) } -> std::same_as<typename SubjectType::const_reverse_iterator>;
};
template<typename SubjectType>
concept member_crbegin = requires(SubjectType const & subject) {
typename SubjectType::const_reverse_iterator;
- {
- subject.crbegin()
- } -> std::same_as<typename SubjectType::const_reverse_iterator>;
+ { subject.crbegin() } -> std::same_as<typename SubjectType::const_reverse_iterator>;
};
template<typename SubjectType>
@@ -368,33 +318,25 @@ namespace nt
template<typename SubjectType>
concept free_end = requires(SubjectType & subject) {
typename SubjectType::iterator;
- {
- end(subject)
- } -> std::same_as<typename SubjectType::iterator>;
+ { end(subject) } -> std::same_as<typename SubjectType::iterator>;
};
template<typename SubjectType>
concept const_free_end = requires(SubjectType const & subject) {
typename SubjectType::const_iterator;
- {
- end(subject)
- } -> std::same_as<typename SubjectType::const_iterator>;
+ { end(subject) } -> std::same_as<typename SubjectType::const_iterator>;
};
template<typename SubjectType>
concept member_end = requires(SubjectType & subject) {
typename SubjectType::iterator;
- {
- subject.end()
- } -> std::same_as<typename SubjectType::iterator>;
+ { subject.end() } -> std::same_as<typename SubjectType::iterator>;
};
template<typename SubjectType>
concept const_member_end = requires(SubjectType const & subject) {
typename SubjectType::const_iterator;
- {
- subject.end()
- } -> std::same_as<typename SubjectType::const_iterator>;
+ { subject.end() } -> std::same_as<typename SubjectType::const_iterator>;
};
template<typename SubjectType>
@@ -406,17 +348,13 @@ namespace nt
template<typename SubjectType>
concept free_cend = requires(SubjectType const & subject) {
typename SubjectType::const_iterator;
- {
- cend(subject)
- } -> std::same_as<typename SubjectType::const_iterator>;
+ { cend(subject) } -> std::same_as<typename SubjectType::const_iterator>;
};
template<typename SubjectType>
concept member_cend = requires(SubjectType const & subject) {
typename SubjectType::const_iterator;
- {
- subject.cend()
- } -> std::same_as<typename SubjectType::const_iterator>;
+ { subject.cend() } -> std::same_as<typename SubjectType::const_iterator>;
};
template<typename SubjectType>
@@ -425,33 +363,25 @@ namespace nt
template<typename SubjectType>
concept free_rend = requires(SubjectType & subject) {
typename SubjectType::reverse_iterator;
- {
- rend(subject)
- } -> std::same_as<typename SubjectType::reverse_iterator>;
+ { rend(subject) } -> std::same_as<typename SubjectType::reverse_iterator>;
};
template<typename SubjectType>
concept const_free_rend = requires(SubjectType const & subject) {
typename SubjectType::const_reverse_iterator;
- {
- rend(subject)
- } -> std::same_as<typename SubjectType::const_reverse_iterator>;
+ { rend(subject) } -> std::same_as<typename SubjectType::const_reverse_iterator>;
};
template<typename SubjectType>
concept member_rend = requires(SubjectType & subject) {
typename SubjectType::reverse_iterator;
- {
- subject.rend()
- } -> std::same_as<typename SubjectType::reverse_iterator>;
+ { subject.rend() } -> std::same_as<typename SubjectType::reverse_iterator>;
};
template<typename SubjectType>
concept const_member_rend = requires(SubjectType const & subject) {
typename SubjectType::const_reverse_iterator;
- {
- subject.rend()
- } -> std::same_as<typename SubjectType::const_reverse_iterator>;
+ { subject.rend() } -> std::same_as<typename SubjectType::const_reverse_iterator>;
};
template<typename SubjectType>
@@ -463,17 +393,13 @@ namespace nt
template<typename SubjectType>
concept free_crend = requires(SubjectType const & subject) {
typename SubjectType::const_reverse_iterator;
- {
- crend(subject)
- } -> std::same_as<typename SubjectType::const_reverse_iterator>;
+ { crend(subject) } -> std::same_as<typename SubjectType::const_reverse_iterator>;
};
template<typename SubjectType>
concept member_crend = requires(SubjectType const & subject) {
typename SubjectType::const_reverse_iterator;
- {
- subject.crend()
- } -> std::same_as<typename SubjectType::const_reverse_iterator>;
+ { subject.crend() } -> std::same_as<typename SubjectType::const_reverse_iterator>;
};
template<typename SubjectType>
@@ -485,12 +411,10 @@ namespace nt
template<typename SubjectType>
concept hashable = requires(SubjectType subject) {
- {
- std::hash<SubjectType>{}(subject)
- } -> std::convertible_to<std::size_t>;
+ { std::hash<SubjectType>{}(subject) } -> std::convertible_to<std::size_t>;
};
- }
+ } // namespace standard_extensions
} // namespace concepts
@@ -509,9 +433,13 @@ namespace nt
auto constexpr ImplicitConversion = derivable<struct implicit_conversion_tag>{};
auto constexpr Indirection = derivable<struct indirection_tag>{};
auto constexpr Iterable = derivable<struct iterable_tag>{};
+#ifdef HAS_I_O_STREAM
auto constexpr Read = derivable<struct read_tag>{};
+#endif
auto constexpr Relational = derivable<struct relational_tag>{};
+#ifdef HAS_I_O_STREAM
auto constexpr Show = derivable<struct show_tag>{};
+#endif
auto constexpr ThreewayCompare = derivable<struct threeway_compare_tag>{};
} // namespace derivables
@@ -605,6 +533,7 @@ namespace nt
return decay();
}
+#ifdef HAS_I_O_STREAM
template<typename CharType, typename StreamTraits, nt::concepts::input_streamable<CharType, StreamTraits> BaseTypeT = BaseType>
auto friend operator>>(std::basic_istream<CharType, StreamTraits> & in,
new_type & obj) noexcept(nt::concepts::nothrow_input_streamable<BaseTypeT, CharType, StreamTraits>)
@@ -622,7 +551,7 @@ namespace nt
{
return out << obj.m_value;
}
-
+#endif
// THREE-WAY ORDER AND EQUAL
auto constexpr operator<=>(new_type const & rhs) const noexcept(nt::concepts::nothrow_three_way_comparable<BaseType>)
@@ -662,7 +591,8 @@ namespace nt
}
#define NEWTYPE_MAKE_LOGICAL_OPERATOR(OPERATOR, CONCEPT) \
- auto constexpr operator OPERATOR(new_type const & rhs) const noexcept(nt::concepts::nothrow_##CONCEPT##_comparable<BaseType>) -> bool \
+ auto constexpr operator OPERATOR(new_type const & rhs) const noexcept(nt::concepts::nothrow_##CONCEPT##_comparable<BaseType>) \
+ ->bool \
requires(nt::concepts::CONCEPT##_comparable<BaseType> && nt::doesnt_derive<derivation_clause_type, nt::ThreewayCompare> && \
nt::derives<derivation_clause_type, nt::Relational>) \
{ \
@@ -676,12 +606,13 @@ namespace nt
#undef NEWTYPE_MAKE_LOGICAL_OPERATOR
#define NEWTYPE_MAKE_ARITHMETIC_OPERATOR(OPERATOR, CONCEPT) \
- auto constexpr operator OPERATOR(new_type const & rhs) const noexcept(nt::concepts::nothrow_##CONCEPT<BaseType>) -> new_type \
+ auto constexpr operator OPERATOR(new_type const & rhs) const noexcept(nt::concepts::nothrow_##CONCEPT<BaseType>) \
+ ->new_type \
requires(nt::concepts::CONCEPT<BaseType> && nt::derives<derivation_clause_type, nt::Arithmetic>) \
{ \
return {decay() OPERATOR rhs.decay()}; \
} \
- auto constexpr operator OPERATOR##=(new_type const & rhs) const noexcept(nt::concepts::nothrow_compound_##CONCEPT<BaseType>) -> new_type & \
+ auto constexpr operator OPERATOR##=(new_type const & rhs) const noexcept(nt::concepts::nothrow_compound_##CONCEPT<BaseType>)->new_type & \
requires(nt::concepts::compound_##CONCEPT<BaseType> && nt::derives<derivation_clause_type, nt::Arithmetic>) { \
return this->m_value OPERATOR## = rhs.decay(), *this; \
};
@@ -694,7 +625,8 @@ namespace nt
#define NEWTYPE_MAKE_ITERATOR_FACTORY_HELPER(NAME, QUALIFICATION, ITERATOR) \
template<nt::concepts::free_##NAME BaseTypeT = BaseType> \
- auto constexpr friend NAME(new_type QUALIFICATION & obj) -> new_type<BaseTypeT, TagType, DerivationClause>::ITERATOR \
+ auto constexpr friend NAME(new_type QUALIFICATION & obj) \
+ ->new_type<BaseTypeT, TagType, DerivationClause>::ITERATOR \
requires nt::derives<decltype(DerivationClause), nt::Iterable> \
{ \
using std::NAME; \