Skip to content

Commit 17c3623

Browse files
committed
Merge branch 'main' into difference_equality
2 parents fbac894 + 8e13c4e commit 17c3623

File tree

4 files changed

+35
-11
lines changed

4 files changed

+35
-11
lines changed

ChangeLog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
* strong::affine_point<D> can now be defaulted as
2+
strong::affine_point<>, in which case a difference type will be
3+
generated using the same tag as the strong affine point type.
4+
15
* operator% is now conditionally supported for arithmetic types,
26
provided that the underlying type supports the operation.
37

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ can thus be used as key in `std::map`<> or `std::set<>`.
114114
one dimentional affine points are pointer (with `D` being `ptrdiff_t`,) or
115115
`std::time_point<>` (with `std::duration<>` as `D`.) An example of a
116116
multidimensional affine point is a coordinate (with a vector type for `D`.)
117+
`D` can be defaulted, using `strong::affine_point<>`, in which case the
118+
difference type shares the same tag.
119+
The difference type from a `strong::affine_point<D>` can be obtained using
120+
`type::difference`, regardless of whether `D` is explicit or defaulted.
117121
It is natural that `D` is of a `strong::difference` type. This is a good name
118122
from a mathematical point of view, but perhaps a bit too academic, and not
119123
well aligned with the other names.
@@ -134,7 +138,7 @@ can thus be used as key in `std::map`<> or `std::set<>`.
134138
135139
* `strong::iterator` adds functionality needed depending on iterator category.
136140
If the iterator type is a `random_access_iterator`, the strong type
137-
is `strong::indexed<>` and `strong::affine_point<difference_type>`. It should be
141+
is `strong::indexed<>` and `strong::affine_point<difference>`. It should be
138142
possible to specify the index type and affine_point type.
139143
140144
* `strong::range` adds the functionality needed to iterate over the elements.

include/strong_type/strong_type.hpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,7 @@ class difference::modifier<::strong::type<T, Tag, M...>>
782782
}
783783
};
784784

785-
template <typename D>
785+
template <typename D = void>
786786
struct affine_point
787787
{
788788
template <typename T>
@@ -809,26 +809,27 @@ class affine_point<D>::modifier<::strong::type<T, Tag, M...>>
809809
{
810810
using type = ::strong::type<T, Tag, M...>;
811811
static_assert(impl::subtractable<T>::value, "it must be possible to subtract instances of your underlying type");
812-
using diff_type = decltype(std::declval<const T&>() - std::declval<const T&>());
813-
static_assert(std::is_constructible<D, diff_type>::value,"");
812+
using base_diff_type = decltype(std::declval<const T&>() - std::declval<const T&>());
814813
public:
814+
using difference = std::conditional_t<std::is_same<D, void>{}, strong::type<base_diff_type, Tag, strong::difference>, D>;
815+
static_assert(std::is_constructible<difference, base_diff_type>::value, "");
815816
STRONG_NODISCARD
816817
friend
817818
STRONG_CONSTEXPR
818-
D
819+
difference
819820
operator-(
820821
const type& lh,
821822
const type& rh)
822823
{
823-
return D(value_of(lh) - value_of(rh));
824+
return difference(value_of(lh) - value_of(rh));
824825
}
825826

826827
friend
827828
STRONG_CONSTEXPR
828829
type&
829830
operator+=(
830831
type& lh,
831-
const D& d)
832+
const difference& d)
832833
noexcept(noexcept(value_of(lh) += impl::access(d)))
833834
{
834835
value_of(lh) += impl::access(d);
@@ -840,7 +841,7 @@ class affine_point<D>::modifier<::strong::type<T, Tag, M...>>
840841
type&
841842
operator-=(
842843
type& lh,
843-
const D& d)
844+
const difference& d)
844845
noexcept(noexcept(value_of(lh) -= impl::access(d)))
845846
{
846847
value_of(lh) -= impl::access(d);
@@ -853,7 +854,7 @@ class affine_point<D>::modifier<::strong::type<T, Tag, M...>>
853854
type
854855
operator+(
855856
type lh,
856-
const D& d)
857+
const difference& d)
857858
{
858859
return lh += d;
859860
}
@@ -863,7 +864,7 @@ class affine_point<D>::modifier<::strong::type<T, Tag, M...>>
863864
STRONG_CONSTEXPR
864865
type
865866
operator+(
866-
const D& d,
867+
const difference& d,
867868
type rh)
868869
{
869870
return rh+= d;
@@ -875,12 +876,13 @@ class affine_point<D>::modifier<::strong::type<T, Tag, M...>>
875876
type
876877
operator-(
877878
type lh,
878-
const D& d)
879+
const difference& d)
879880
{
880881
return lh -= d;
881882
}
882883
};
883884

885+
884886
struct pointer
885887
{
886888
template <typename T>

test.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,9 @@ static_assert(is_addable<dhandle,handle>{},"");
319319
static_assert(is_addable<handle,dhandle>{},"");
320320
static_assert(!is_range<dhandle>{}, "");
321321

322+
using ddhandle = strong::type<int, struct int_tag, strong::affine_point<>>;
323+
static_assert(std::is_same<ddhandle::difference, strong::type<int, struct int_tag, strong::difference>>{}, "");
324+
322325
using ri = strong::type<int*, struct ipt, strong::iterator>;
323326

324327
static_assert(!std::is_default_constructible<ri>{},"");
@@ -987,6 +990,17 @@ TEST_CASE("affine_point types can be subtracted")
987990
REQUIRE(value_of(d) == 5);
988991
}
989992

993+
TEST_CASE("affine point type with defaulted difference type yields it when subtracting")
994+
{
995+
using T = strong::type<int, struct i_, strong::affine_point<>>;
996+
997+
T t1{3};
998+
T t2{8};
999+
auto d = t2 - t1;
1000+
static_assert(std::is_same<decltype(d), strong::type<int, struct i_, strong::difference>>{},"");
1001+
REQUIRE(value_of(d) == 5);
1002+
}
1003+
9901004
TEST_CASE("affine_point types can be added with the delta type")
9911005
{
9921006
using D = strong::type<int, struct i_>;

0 commit comments

Comments
 (0)