strongdef: don't expose the raw data directly

This commit is contained in:
Danny Robson 2019-03-20 15:39:24 +11:00
parent 83cd6074b8
commit 065daa96c6
3 changed files with 15 additions and 14 deletions

View File

@ -13,4 +13,4 @@
// This instantiation is not meant to be exported, only being used as a local // This instantiation is not meant to be exported, only being used as a local
// compilation error canary. // compilation error canary.
template struct cruft::strongdef::index<void,unsigned>; template class cruft::strongdef::index<void,unsigned>;

View File

@ -20,7 +20,8 @@ namespace cruft::strongdef {
/// A transparent wrapper around a (typically lightweight) type for the /// A transparent wrapper around a (typically lightweight) type for the
/// purposes of overload disambiguation. It acts like a typesafe typedef. /// purposes of overload disambiguation. It acts like a typesafe typedef.
template <typename TagT, typename T = typename TagT::index_type> template <typename TagT, typename T = typename TagT::index_type>
struct index { class index {
public:
using value_type = T; using value_type = T;
using tag_type = TagT; using tag_type = TagT;
@ -59,7 +60,14 @@ namespace cruft::strongdef {
constexpr auto& operator++ (void)& { ++data; return *this; } constexpr auto& operator++ (void)& { ++data; return *this; }
T data; constexpr T * operator-> () &{ return &data; }
constexpr T const* operator-> () const &{ return &data; }
constexpr T & operator* () &{ return data; }
constexpr T const& operator* () const &{ return data; }
private:
value_type data;
}; };
@ -67,7 +75,7 @@ namespace cruft::strongdef {
std::ostream& std::ostream&
operator<< (std::ostream &os, index<TagT,T> const &val) operator<< (std::ostream &os, index<TagT,T> const &val)
{ {
return os << +val.data; return os << +*val;
} }
} }
@ -89,7 +97,7 @@ static auto indices (ContainerT const &obj)
iterator& operator++ () iterator& operator++ ()
{ {
++idx.data; ++idx;
return *this; return *this;
} }

View File

@ -10,15 +10,8 @@ main (void)
// These tests are less about functional testing, and more about link testing. // These tests are less about functional testing, and more about link testing.
cruft::strongdef::index<void,unsigned> fortytwo (42u); cruft::strongdef::index<void,unsigned> fortytwo (42u);
tap.expect_eq (fortytwo.data, 42u, "raw data equality"); tap.expect_eq (*fortytwo, 42u, "raw data equality");
tap.expect_eq (fortytwo, decltype(fortytwo) (42u), "passthrough equality"); tap.expect_eq ( fortytwo, decltype(fortytwo) (42u), "passthrough equality");
#if 0
// Ensure numeric_limits has been specialised. Unknown types are default initialised, so check if we get non-zero for maximum.
tap.expect_eq (std::numeric_limits<decltype(fortytwo)>::max (),
std::numeric_limits<decltype(fortytwo)::value_type>::max (),
"numeric_limits has been specialised");
#endif
return tap.status (); return tap.status ();
} }