diff --git a/include/strong_type/affine_point.hpp b/include/strong_type/affine_point.hpp index a25e74a..95df5bc 100644 --- a/include/strong_type/affine_point.hpp +++ b/include/strong_type/affine_point.hpp @@ -18,7 +18,7 @@ namespace strong { -template +STRONG_TYPE_MODULE_EXPORT template struct affine_point { template @@ -36,6 +36,7 @@ struct subtractable() - std::declval template class affine_point::modifier<::strong::type> diff --git a/include/strong_type/arithmetic.hpp b/include/strong_type/arithmetic.hpp index d1b3f8f..cdffbcf 100644 --- a/include/strong_type/arithmetic.hpp +++ b/include/strong_type/arithmetic.hpp @@ -20,7 +20,7 @@ namespace strong { -struct arithmetic { +STRONG_TYPE_MODULE_EXPORT struct arithmetic { template class modifier { @@ -29,7 +29,7 @@ struct arithmetic { }; }; -template +STRONG_TYPE_MODULE_EXPORT template class arithmetic::modifier, impl::void_t() * std::declval() - std::declval() / std::declval())>> { using type = strong::type; @@ -170,7 +170,7 @@ class arithmetic::modifier, impl::void_t +STRONG_TYPE_MODULE_EXPORT template #if defined(__cpp_concepts) requires strong::type_is_v, strong::arithmetic> class std::numeric_limits> diff --git a/include/strong_type/bicrementable.hpp b/include/strong_type/bicrementable.hpp index 9b0d06c..0e0e6f5 100644 --- a/include/strong_type/bicrementable.hpp +++ b/include/strong_type/bicrementable.hpp @@ -19,7 +19,7 @@ namespace strong { -struct bicrementable +STRONG_TYPE_MODULE_EXPORT struct bicrementable { template class modifier diff --git a/include/strong_type/bitarithmetic.hpp b/include/strong_type/bitarithmetic.hpp index 0e40795..ca8575f 100644 --- a/include/strong_type/bitarithmetic.hpp +++ b/include/strong_type/bitarithmetic.hpp @@ -18,7 +18,7 @@ namespace strong { -struct bitarithmetic +STRONG_TYPE_MODULE_EXPORT struct bitarithmetic { template class modifier diff --git a/include/strong_type/boolean.hpp b/include/strong_type/boolean.hpp index f4281d1..e1effba 100644 --- a/include/strong_type/boolean.hpp +++ b/include/strong_type/boolean.hpp @@ -18,7 +18,7 @@ namespace strong { -struct boolean +STRONG_TYPE_MODULE_EXPORT struct boolean { template class modifier diff --git a/include/strong_type/convertible_to.hpp b/include/strong_type/convertible_to.hpp index 1e0423c..03bd373 100644 --- a/include/strong_type/convertible_to.hpp +++ b/include/strong_type/convertible_to.hpp @@ -43,7 +43,7 @@ struct converter< } -template +STRONG_TYPE_MODULE_EXPORT template struct convertible_to { template diff --git a/include/strong_type/decrementable.hpp b/include/strong_type/decrementable.hpp index eb06350..3a36c2a 100644 --- a/include/strong_type/decrementable.hpp +++ b/include/strong_type/decrementable.hpp @@ -18,7 +18,7 @@ namespace strong { -struct decrementable +STRONG_TYPE_MODULE_EXPORT struct decrementable { template class modifier diff --git a/include/strong_type/difference.hpp b/include/strong_type/difference.hpp index e6ca121..7451256 100644 --- a/include/strong_type/difference.hpp +++ b/include/strong_type/difference.hpp @@ -85,13 +85,13 @@ class conditionally_ordered::modifier<::strong::type> } }; } -struct difference +STRONG_TYPE_MODULE_EXPORT struct difference { template class modifier; }; -template +STRONG_TYPE_MODULE_EXPORT template class difference::modifier<::strong::type> : public impl::conditionally_ordered::modifier<::strong::type> , public equality::modifier<::strong::type> diff --git a/include/strong_type/equality.hpp b/include/strong_type/equality.hpp index ab500f9..e2c9fc4 100644 --- a/include/strong_type/equality.hpp +++ b/include/strong_type/equality.hpp @@ -18,7 +18,7 @@ namespace strong { -struct equality +STRONG_TYPE_MODULE_EXPORT struct equality { template class modifier { @@ -28,7 +28,7 @@ struct equality }; -template +STRONG_TYPE_MODULE_EXPORT template class equality::modifier< ::strong::type, impl::void_t() == std::declval())> diff --git a/include/strong_type/equality_with.hpp b/include/strong_type/equality_with.hpp index f1c928e..10909dd 100644 --- a/include/strong_type/equality_with.hpp +++ b/include/strong_type/equality_with.hpp @@ -76,7 +76,7 @@ class typed_equality< }; } -template +STRONG_TYPE_MODULE_EXPORT template struct equality_with { template diff --git a/include/strong_type/formattable.hpp b/include/strong_type/formattable.hpp index ec0816c..5f75389 100644 --- a/include/strong_type/formattable.hpp +++ b/include/strong_type/formattable.hpp @@ -51,7 +51,7 @@ namespace strong { -struct formattable +STRONG_TYPE_MODULE_EXPORT struct formattable { template class modifier{}; diff --git a/include/strong_type/hashable.hpp b/include/strong_type/hashable.hpp index 01c9ee9..aa33df0 100644 --- a/include/strong_type/hashable.hpp +++ b/include/strong_type/hashable.hpp @@ -20,7 +20,7 @@ namespace strong { -struct hashable +STRONG_TYPE_MODULE_EXPORT struct hashable { template class modifier{}; @@ -29,7 +29,7 @@ struct hashable } namespace std { -template +STRONG_TYPE_MODULE_EXPORT template struct hash<::strong::type> : std::conditional_t< std::is_base_of< diff --git a/include/strong_type/implicitly_convertible_to.hpp b/include/strong_type/implicitly_convertible_to.hpp index 2e8018f..e1fd167 100644 --- a/include/strong_type/implicitly_convertible_to.hpp +++ b/include/strong_type/implicitly_convertible_to.hpp @@ -42,7 +42,7 @@ struct implicit_converter< }; } -template +STRONG_TYPE_MODULE_EXPORT template struct implicitly_convertible_to { template diff --git a/include/strong_type/incrementable.hpp b/include/strong_type/incrementable.hpp index 4f7b525..74d30c7 100644 --- a/include/strong_type/incrementable.hpp +++ b/include/strong_type/incrementable.hpp @@ -17,7 +17,7 @@ #include "type.hpp" namespace strong { -struct incrementable +STRONG_TYPE_MODULE_EXPORT struct incrementable { template class modifier diff --git a/include/strong_type/indexed.hpp b/include/strong_type/indexed.hpp index fec160d..ea7a6a5 100644 --- a/include/strong_type/indexed.hpp +++ b/include/strong_type/indexed.hpp @@ -18,7 +18,7 @@ namespace strong { -template +STRONG_TYPE_MODULE_EXPORT template struct indexed { template @@ -29,7 +29,7 @@ struct indexed }; }; -template <> +STRONG_TYPE_MODULE_EXPORT template <> struct indexed { template class modifier; @@ -112,7 +112,7 @@ struct indexed { }; }; -template +STRONG_TYPE_MODULE_EXPORT template template class indexed::modifier< type, diff --git a/include/strong_type/invocable.hpp b/include/strong_type/invocable.hpp index 8306a5d..96435af 100644 --- a/include/strong_type/invocable.hpp +++ b/include/strong_type/invocable.hpp @@ -20,13 +20,13 @@ namespace strong { -struct invocable +STRONG_TYPE_MODULE_EXPORT struct invocable { template class modifier; }; -template +STRONG_TYPE_MODULE_EXPORT template class invocable::modifier> { using type = strong::type; diff --git a/include/strong_type/iostreamable.hpp b/include/strong_type/iostreamable.hpp index 8f21b4f..160dcd7 100644 --- a/include/strong_type/iostreamable.hpp +++ b/include/strong_type/iostreamable.hpp @@ -19,7 +19,7 @@ namespace strong { -struct iostreamable +STRONG_TYPE_MODULE_EXPORT struct iostreamable { template class modifier diff --git a/include/strong_type/istreamable.hpp b/include/strong_type/istreamable.hpp index 56e0535..476572d 100644 --- a/include/strong_type/istreamable.hpp +++ b/include/strong_type/istreamable.hpp @@ -20,7 +20,7 @@ namespace strong { -struct istreamable +STRONG_TYPE_MODULE_EXPORT struct istreamable { template class modifier diff --git a/include/strong_type/iterator.hpp b/include/strong_type/iterator.hpp index c6cf39e..87102c6 100644 --- a/include/strong_type/iterator.hpp +++ b/include/strong_type/iterator.hpp @@ -64,7 +64,7 @@ namespace internal { }; } -class iterator +STRONG_TYPE_MODULE_EXPORT class iterator { public: template class modifier @@ -31,7 +31,7 @@ struct ordered }; }; - +STRONG_TYPE_MODULE_EXPORT template class ordered::modifier< ::strong::type, @@ -108,7 +108,7 @@ struct spaceship_ordering { struct modifier; }; -template +STRONG_TYPE_MODULE_EXPORT template template struct spaceship_ordering::modifier<::strong::type> { @@ -131,9 +131,9 @@ struct spaceship_ordering::modifier<::strong::type> } -using strongly_ordered = detail::spaceship_ordering; -using weakly_ordered = detail::spaceship_ordering; -using partially_ordered = detail::spaceship_ordering; +STRONG_TYPE_MODULE_EXPORT using strongly_ordered = detail::spaceship_ordering; +STRONG_TYPE_MODULE_EXPORT using weakly_ordered = detail::spaceship_ordering; +STRONG_TYPE_MODULE_EXPORT using partially_ordered = detail::spaceship_ordering; #endif diff --git a/include/strong_type/ordered_with.hpp b/include/strong_type/ordered_with.hpp index c44fd91..c36f243 100644 --- a/include/strong_type/ordered_with.hpp +++ b/include/strong_type/ordered_with.hpp @@ -125,7 +125,7 @@ class typed_ordering< }; } -template +STRONG_TYPE_MODULE_EXPORT template struct ordered_with { template @@ -171,11 +171,11 @@ struct spaceship_ordering_with } -template +STRONG_TYPE_MODULE_EXPORT template using strongly_ordered_with = detail::spaceship_ordering_with; -template +STRONG_TYPE_MODULE_EXPORT template using weakly_ordered_with = detail::spaceship_ordering_with; -template +STRONG_TYPE_MODULE_EXPORT template using partially_ordered_with = detail::spaceship_ordering_with; #endif diff --git a/include/strong_type/ostreamable.hpp b/include/strong_type/ostreamable.hpp index 146ca95..39c8209 100644 --- a/include/strong_type/ostreamable.hpp +++ b/include/strong_type/ostreamable.hpp @@ -20,7 +20,7 @@ namespace strong { -struct ostreamable +STRONG_TYPE_MODULE_EXPORT struct ostreamable { template class modifier @@ -43,7 +43,7 @@ struct ostreamable }; }; -template +STRONG_TYPE_MODULE_EXPORT template using is_ostreamable = std::is_base_of, T>; } diff --git a/include/strong_type/pointer.hpp b/include/strong_type/pointer.hpp index f6b3851..1a42a8f 100644 --- a/include/strong_type/pointer.hpp +++ b/include/strong_type/pointer.hpp @@ -18,19 +18,19 @@ namespace strong { -struct pointer +STRONG_TYPE_MODULE_EXPORT struct pointer { template class modifier; }; -template +STRONG_TYPE_MODULE_EXPORT template class pointer::modifier { static_assert(impl::always_false, "Underlying type must support dereferencing with operator*"); }; -template +STRONG_TYPE_MODULE_EXPORT template class pointer::modifier<::strong::type, impl::void_t())>> { using type = strong::type; diff --git a/include/strong_type/range.hpp b/include/strong_type/range.hpp index c7cdf09..61aab6e 100644 --- a/include/strong_type/range.hpp +++ b/include/strong_type/range.hpp @@ -128,7 +128,7 @@ constexpr bool is_random_access(std::output_iterator_tag) { return false;} #define STRONG_TYPE_CEND(x) x.cend() #endif -class range +STRONG_TYPE_MODULE_EXPORT class range { public: template < @@ -142,7 +142,7 @@ class range class modifier; }; -template +STRONG_TYPE_MODULE_EXPORT template class range::modifier< R, internal::not_an_iterator, internal::not_an_iterator, @@ -155,7 +155,7 @@ class range::modifier< }; -template +STRONG_TYPE_MODULE_EXPORT template class range::modifier< type, iterator, iterator, @@ -165,7 +165,7 @@ class range::modifier< static_assert(impl::always_false, "the underlying type is lying about its iterator type"); }; -template +STRONG_TYPE_MODULE_EXPORT template class range::modifier< type, r_iterator, r_iterator, @@ -260,7 +260,7 @@ class range::modifier< } }; -template +STRONG_TYPE_MODULE_EXPORT template class range::modifier< type, r_iterator, r_sentinel, @@ -356,7 +356,7 @@ class range::modifier< } }; -template +STRONG_TYPE_MODULE_EXPORT template class range::modifier< type, r_iterator, r_iterator, @@ -401,7 +401,7 @@ class range::modifier< } }; -template +STRONG_TYPE_MODULE_EXPORT template class range::modifier< type, r_iterator, r_sentinel, @@ -447,7 +447,7 @@ class range::modifier< } }; -template +STRONG_TYPE_MODULE_EXPORT template class range::modifier< type, internal::not_an_iterator, internal::not_an_iterator, diff --git a/include/strong_type/regular.hpp b/include/strong_type/regular.hpp index c44b494..0298606 100644 --- a/include/strong_type/regular.hpp +++ b/include/strong_type/regular.hpp @@ -19,7 +19,7 @@ namespace strong { -struct regular +STRONG_TYPE_MODULE_EXPORT struct regular { template class modifier diff --git a/include/strong_type/scalable_with.hpp b/include/strong_type/scalable_with.hpp index 51f9b08..5cbc1f3 100644 --- a/include/strong_type/scalable_with.hpp +++ b/include/strong_type/scalable_with.hpp @@ -103,7 +103,7 @@ class typed_scalable< }; } -template +STRONG_TYPE_MODULE_EXPORT template struct scalable_with { template @@ -115,7 +115,7 @@ struct scalable_with }; } -template < +STRONG_TYPE_MODULE_EXPORT template < typename TT, typename UT = strong::underlying_type_t, typename R = typename TT::scalable_modifier_result_type, diff --git a/include/strong_type/semiregular.hpp b/include/strong_type/semiregular.hpp index 832abcd..d026bce 100644 --- a/include/strong_type/semiregular.hpp +++ b/include/strong_type/semiregular.hpp @@ -31,13 +31,13 @@ struct require_semiregular }; } -struct semiregular +STRONG_TYPE_MODULE_EXPORT struct semiregular { template class modifier; }; -template +STRONG_TYPE_MODULE_EXPORT template class semiregular::modifier<::strong::type> : public default_constructible::modifier , private impl::require_semiregular diff --git a/include/strong_type/strong_ordering.hpp b/include/strong_type/strong_ordering.hpp index 55fe032..ea74a62 100644 --- a/include/strong_type/strong_ordering.hpp +++ b/include/strong_type/strong_ordering.hpp @@ -7,13 +7,13 @@ namespace strong { -struct strong_ordering +STRONG_TYPE_MODULE_EXPORT struct strong_ordering { template class modifier; }; -template +STRONG_TYPE_MODULE_EXPORT template class strong_ordering::modifier<::strong::type> { using type = ::strong::type; diff --git a/include/strong_type/strong_type.ixx b/include/strong_type/strong_type.ixx new file mode 100644 index 0000000..2d5132e --- /dev/null +++ b/include/strong_type/strong_type.ixx @@ -0,0 +1,57 @@ +/* + * strong_type C++14/17/20 strong typedef library + * + * Copyright (C) Björn Fahller + * + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * Project home: https://github.com/rollbear/strong_type + */ + +module; + +#include + +#define STRONG_TYPE_MODULE +#define STRONG_TYPE_MODULE_EXPORT export +#define STRONG_TYPE_IMPORT_STD_LIBRARY + +export module strong_type; + +// Currently this just uses the std library module. This should be changed to allow the strong_type module to optionally use +// inport or include of the standard library +import std; + +#include "affine_point.hpp" +#include "arithmetic.hpp" +#include "bicrementable.hpp" +#include "bitarithmetic.hpp" +#include "boolean.hpp" +#include "convertible_to.hpp" +#include "decrementable.hpp" +#include "difference.hpp" +#include "equality.hpp" +#include "equality_with.hpp" +#include "formattable.hpp" +#include "hashable.hpp" +#include "implicitly_convertible_to.hpp" +#include "incrementable.hpp" +#include "indexed.hpp" +#include "invocable.hpp" +#include "iostreamable.hpp" +#include "istreamable.hpp" +#include "iterator.hpp" +#include "ordered.hpp" +#include "ordered_with.hpp" +#include "ostreamable.hpp" +#include "pointer.hpp" +#include "range.hpp" +#include "regular.hpp" +#include "scalable_with.hpp" +#include "semiregular.hpp" +#include "strong_ordering.hpp" +#include "type.hpp" +#include "unique.hpp" diff --git a/include/strong_type/type.hpp b/include/strong_type/type.hpp index 4906f34..2f4e79e 100644 --- a/include/strong_type/type.hpp +++ b/include/strong_type/type.hpp @@ -31,16 +31,21 @@ #define STRONG_NODISCARD #endif +// For users including rather than importing the header we don't want to force them to define STRONG_TYPE_MODULE_EXPORT so if not defined define it to be empty +#if !defined(STRONG_TYPE_MODULE_EXPORT) +#define STRONG_TYPE_MODULE_EXPORT +#endif + namespace strong { -struct uninitialized_t { +STRONG_TYPE_MODULE_EXPORT struct uninitialized_t { }; -static constexpr uninitialized_t uninitialized{}; +STRONG_TYPE_MODULE_EXPORT constexpr uninitialized_t uninitialized{}; -template +STRONG_TYPE_MODULE_EXPORT template using modifier = typename M::template modifier; -struct default_constructible { +STRONG_TYPE_MODULE_EXPORT struct default_constructible { template class modifier { }; @@ -58,7 +63,7 @@ template using WhenConstructible = std::enable_if_t::value>; } -template +STRONG_TYPE_MODULE_EXPORT template class type : public modifier> ... { public: template{}>> @@ -157,23 +162,23 @@ constexpr T underlying_type(strong::type *); } -template +STRONG_TYPE_MODULE_EXPORT template struct is_strong_type : std::integral_constant(nullptr))> { }; -template::value> +STRONG_TYPE_MODULE_EXPORT template::value> struct underlying_type { using type = decltype(impl::underlying_type(static_cast(nullptr))); }; -template +STRONG_TYPE_MODULE_EXPORT template struct underlying_type { using type = T; }; -template +STRONG_TYPE_MODULE_EXPORT template using underlying_type_t = typename underlying_type::type; namespace impl { @@ -182,7 +187,8 @@ using WhenStrongType = std::enable_if_t>::value>; template using WhenNotStrongType = std::enable_if_t>::value>; -template< +// This is used in the implementation of public functions so must be exported +STRONG_TYPE_MODULE_EXPORT template< typename T, typename = impl::WhenNotStrongType> constexpr @@ -193,7 +199,8 @@ noexcept return std::forward(t); } -template< +// This is used in the implementation of public functions so must be exported +STRONG_TYPE_MODULE_EXPORT template< typename T, typename = impl::WhenStrongType> STRONG_NODISCARD @@ -354,10 +361,10 @@ template using get_strong = decltype(get_strong_(static_cast(nullptr))); } -template -static constexpr bool type_is_v = impl::type_is, M>; +STRONG_TYPE_MODULE_EXPORT template +constexpr bool type_is_v = impl::type_is, M>; -template +STRONG_TYPE_MODULE_EXPORT template using type_is = std::integral_constant>; } diff --git a/include/strong_type/unique.hpp b/include/strong_type/unique.hpp index a630d06..753fff7 100644 --- a/include/strong_type/unique.hpp +++ b/include/strong_type/unique.hpp @@ -18,7 +18,7 @@ namespace strong { -struct unique { +STRONG_TYPE_MODULE_EXPORT struct unique { template class modifier : private impl::valid_type<