Skip to content

Commit

Permalink
Reduce macro complexity for copyable vs. move_only
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickroberts committed Feb 9, 2025
1 parent 61d2069 commit 10c358c
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 103 deletions.
21 changes: 12 additions & 9 deletions include/beman/any_view/any_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,11 @@ class any_view : public std::ranges::view_interface<any_view<ElementT, OptionsV,

static constexpr bool sized = (OptionsV & any_view_options::sized) == any_view_options::sized;
static constexpr bool copyable =
#if BEMAN_ANY_VIEW_USE_MOVE_ONLY()
not
#if BEMAN_ANY_VIEW_USE_COPYABLE()
(OptionsV & any_view_options::copyable) == any_view_options::copyable;
#elif BEMAN_ANY_VIEW_USE_MOVE_ONLY()
(OptionsV & any_view_options::move_only) != any_view_options::move_only;
#endif
((OptionsV & any_view_options::BEMAN_ANY_VIEW_OPTION()) == any_view_options::BEMAN_ANY_VIEW_OPTION());

using interface_type = detail::view_interface<iterator_concept, ElementT, RefT, RValueRefT, DiffT>;
// inplace storage sufficient for a vtable pointer and a std::vector<T>
Expand Down Expand Up @@ -111,10 +112,11 @@ class any_view : public std::ranges::view_interface<any_view<ElementT, RangeTrai

static constexpr bool sized = detail::sized_or_v<false, RangeTraitsT>;
static constexpr bool copyable =
#if BEMAN_ANY_VIEW_USE_MOVE_ONLY()
not
#if BEMAN_ANY_VIEW_USE_COPYABLE()
detail::copyable_or_v<false, RangeTraitsT>;
#elif BEMAN_ANY_VIEW_USE_MOVE_ONLY()
not detail::move_only_or_v<false, RangeTraitsT>;
#endif
detail::BEMAN_ANY_VIEW_OPTION_(or_v)<false, RangeTraitsT>;

using interface_type =
detail::view_interface<iterator_concept, ElementT, reference_type, rvalue_reference_type, difference_type>;
Expand Down Expand Up @@ -174,10 +176,11 @@ class any_view : public std::ranges::view_interface<any_view<ElementT, OptionsV>

static constexpr bool sized = OptionsV.sized;
static constexpr bool copyable =
#if BEMAN_ANY_VIEW_USE_MOVE_ONLY()
not
#if BEMAN_ANY_VIEW_USE_COPYABLE()
OptionsV.copyable;
#elif BEMAN_ANY_VIEW_USE_MOVE_ONLY()
not OptionsV.move_only;
#endif
OptionsV.BEMAN_ANY_VIEW_OPTION();

using interface_type =
detail::view_interface<iterator_concept, ElementT, reference_type, rvalue_reference_type, difference_type>;
Expand Down
36 changes: 22 additions & 14 deletions include/beman/any_view/any_view_options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,18 @@ namespace beman::any_view {
#if BEMAN_ANY_VIEW_USE_ENUM()

enum class any_view_options {
input = 0b0000000,
forward = 0b0000001,
bidirectional = 0b0000011,
random_access = 0b0000111,
contiguous = 0b0001111,
sized = 0b0010000,
borrowed = 0b0100000,
BEMAN_ANY_VIEW_OPTION() = 0b1000000,
input = 0b0000000,
forward = 0b0000001,
bidirectional = 0b0000011,
random_access = 0b0000111,
contiguous = 0b0001111,
sized = 0b0010000,
borrowed = 0b0100000,
#if BEMAN_ANY_VIEW_USE_COPYABLE()
copyable = 0b1000000,
#elif BEMAN_ANY_VIEW_USE_MOVE_ONLY()
move_only = 0b1000000,
#endif
};

[[nodiscard]] constexpr auto operator|(any_view_options l, any_view_options r) noexcept -> any_view_options {
Expand Down Expand Up @@ -92,12 +96,16 @@ template <class RefT,
class DiffT = std::ptrdiff_t>
struct any_view_options {
type_t<RefT> reference_type;
type_t<IterConceptT> iterator_concept = {};
bool sized = false;
bool BEMAN_ANY_VIEW_OPTION() = false;
bool borrowed = false;
type_t<RValueRefT> rvalue_reference_type = {};
type_t<DiffT> difference_type = {};
type_t<IterConceptT> iterator_concept = {};
bool sized = false;
#if BEMAN_ANY_VIEW_USE_COPYABLE()
bool copyable = false;
#elif BEMAN_ANY_VIEW_USE_MOVE_ONLY()
bool move_only = false;
#endif
bool borrowed = false;
type_t<RValueRefT> rvalue_reference_type = {};
type_t<DiffT> difference_type = {};
};

#endif
Expand Down
7 changes: 4 additions & 3 deletions include/beman/any_view/concepts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ concept borrowed_range_compatible_with = not RangeTraitsT::borrowed or std::rang
template <class ViewT, class RangeTraitsT>
concept copyable_view_compatible_with =
#if BEMAN_ANY_VIEW_USE_COPYABLE()
not
not RangeTraitsT::copyable
#elif BEMAN_ANY_VIEW_USE_MOVE_ONLY()
RangeTraitsT::move_only
#endif
RangeTraitsT::BEMAN_ANY_VIEW_OPTION() or
std::copyable<ViewT>;
or std::copyable<ViewT>;

template <class ViewT, class RangeTraitsT>
concept view_compatible_with =
Expand Down
10 changes: 0 additions & 10 deletions include/beman/any_view/config.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,4 @@
#cmakedefine01 BEMAN_ANY_VIEW_USE_COPYABLE()
#cmakedefine01 BEMAN_ANY_VIEW_USE_MOVE_ONLY()

#if BEMAN_ANY_VIEW_USE_COPYABLE()
#define BEMAN_ANY_VIEW_OPTION() copyable
#define BEMAN_ANY_VIEW_OPTION_(suffix) copyable_##suffix
#elif BEMAN_ANY_VIEW_USE_MOVE_ONLY()
#define BEMAN_ANY_VIEW_OPTION() move_only
#define BEMAN_ANY_VIEW_OPTION_(suffix) move_only_##suffix
#endif

#define BEMAN_ANY_VIEW_CAT(a, b) a##b

#endif // BEMAN_ANY_VIEW_CONFIG_HPP
4 changes: 2 additions & 2 deletions include/beman/any_view/detail/iterator_adaptor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ template <class ElementT,
class DiffT,
std::input_or_output_iterator IteratorT,
std::sentinel_for<IteratorT> SentinelT>
class iterator_adaptor : public iterator_interface<ElementT, RefT, RValueRefT, DiffT> {
class iterator_adaptor final : public iterator_interface<ElementT, RefT, RValueRefT, DiffT> {
[[no_unique_address]] IteratorT iterator;
[[no_unique_address]] SentinelT sentinel;

Expand Down Expand Up @@ -139,7 +139,7 @@ class iterator_adaptor : public iterator_interface<ElementT, RefT, RValueRefT, D
return iterator == sentinel;
}

// ICE workaround for GCC
// workaround https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104653
constexpr ~iterator_adaptor() noexcept override {}
};

Expand Down
4 changes: 2 additions & 2 deletions include/beman/any_view/detail/view_adaptor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
namespace beman::any_view::detail {

template <class IterConceptT, class ElementT, class RefT, class RValueRefT, class DiffT, std::ranges::view ViewT>
class view_adaptor : public view_interface<IterConceptT, ElementT, RefT, RValueRefT, DiffT> {
class view_adaptor final : public view_interface<IterConceptT, ElementT, RefT, RValueRefT, DiffT> {
using iterator = detail::any_iterator<IterConceptT, ElementT, RefT, RValueRefT, DiffT>;
using size_type = std::make_unsigned_t<DiffT>;

Expand Down Expand Up @@ -67,7 +67,7 @@ class view_adaptor : public view_interface<IterConceptT, ElementT, RefT, RValueR
}
}

// ICE workaround for GCC
// workaround https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104653
constexpr ~view_adaptor() noexcept override {}
};

Expand Down
27 changes: 15 additions & 12 deletions include/beman/any_view/range_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,20 @@ BEMAN_ANY_VIEW_TYPE_TRAIT(difference_type);

#undef BEMAN_ANY_VIEW_TYPE_TRAIT

#define BEMAN_ANY_VIEW_BOOL_TRAIT(name) \
template <class RangeTraitsT> \
using name = std::bool_constant<RangeTraitsT::name>; \
\
template <bool DefaultV, class RangeTraitsT> \
inline constexpr bool BEMAN_ANY_VIEW_CAT(name, _or_v) = \
detected_or_t<std::bool_constant<DefaultV>, name, RangeTraitsT>::value
#define BEMAN_ANY_VIEW_BOOL_TRAIT(name) \
template <class RangeTraitsT> \
using name = std::bool_constant<RangeTraitsT::name>; \
\
template <bool DefaultV, class RangeTraitsT> \
inline constexpr bool name##_or_v = detected_or_t<std::bool_constant<DefaultV>, name, RangeTraitsT>::value

BEMAN_ANY_VIEW_BOOL_TRAIT(sized);
BEMAN_ANY_VIEW_BOOL_TRAIT(borrowed);
BEMAN_ANY_VIEW_BOOL_TRAIT(BEMAN_ANY_VIEW_OPTION());
#if BEMAN_ANY_VIEW_USE_COPYABLE()
BEMAN_ANY_VIEW_BOOL_TRAIT(copyable);
#elif BEMAN_ANY_VIEW_USE_MOVE_ONLY()
BEMAN_ANY_VIEW_BOOL_TRAIT(move_only);
#endif

#undef BEMAN_ANY_VIEW_BOOL_TRAIT

Expand All @@ -80,11 +83,11 @@ struct range_traits {

static constexpr bool sized = std::ranges::sized_range<RangeT>;
static constexpr bool borrowed = std::ranges::borrowed_range<RangeT>;
static constexpr bool BEMAN_ANY_VIEW_OPTION() =
#if BEMAN_ANY_VIEW_USE_MOVE_ONLY()
not
#if BEMAN_ANY_VIEW_USE_COPYABLE()
static constexpr bool copyable = std::copyable<RangeT>;
#elif BEMAN_ANY_VIEW_USE_MOVE_ONLY()
static constexpr bool move_only = not std::copyable<RangeT>;
#endif
std::copyable<RangeT>;
};

} // namespace beman::any_view
Expand Down
24 changes: 15 additions & 9 deletions tests/beman/any_view/options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,11 @@ inline constexpr any_view_options move_only_options{

template <class IterConceptT>
inline constexpr any_view_options iterator_options{
.reference_type = default_reference_type,
.iterator_concept = type<IterConceptT>,
.BEMAN_ANY_VIEW_OPTION() = move_only_options.BEMAN_ANY_VIEW_OPTION(),
.reference_type = default_reference_type,
.iterator_concept = type<IterConceptT>,
#if BEMAN_ANY_VIEW_USE_MOVE_ONLY()
.move_only = true,
#endif
};

inline constexpr auto input_options = iterator_options<std::input_iterator_tag>;
Expand All @@ -102,15 +104,19 @@ inline constexpr auto random_access_options = iterator_options<std::random_acces
inline constexpr auto contiguous_options = iterator_options<std::contiguous_iterator_tag>;

inline constexpr any_view_options sized_options{
.reference_type = default_reference_type,
.sized = true,
.BEMAN_ANY_VIEW_OPTION() = move_only_options.BEMAN_ANY_VIEW_OPTION(),
.reference_type = default_reference_type,
.sized = true,
#if BEMAN_ANY_VIEW_USE_MOVE_ONLY()
.move_only = true,
#endif
};

inline constexpr any_view_options borrowed_options{
.reference_type = default_reference_type,
.BEMAN_ANY_VIEW_OPTION() = move_only_options.BEMAN_ANY_VIEW_OPTION(),
.borrowed = true,
.reference_type = default_reference_type,
#if BEMAN_ANY_VIEW_USE_MOVE_ONLY()
.move_only = true,
#endif
.borrowed = true,
};

#endif
Expand Down
94 changes: 52 additions & 42 deletions tests/beman/any_view/sfinae.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,48 +92,58 @@ TEST(SfinaeTest, vector_of_bool) {
static_assert(std::constructible_from<any_view<bool, traits<borrowed_options>>, std::vector<bool>&>);
static_assert(std::constructible_from<any_view<bool, traits<copyable_options>>, std::vector<bool>&>);
#elif BEMAN_ANY_VIEW_USE_NAMED()
static_assert(
std::constructible_from<any_view<bool,
{.reference_type = type<bool>,
.iterator_concept = type<std::random_access_iterator_tag>,
.BEMAN_ANY_VIEW_OPTION() = move_only_options.BEMAN_ANY_VIEW_OPTION()}>,
std::vector<bool>>);
static_assert(
std::constructible_from<any_view<bool,
{.reference_type = type<bool>,
.sized = true,
.BEMAN_ANY_VIEW_OPTION() = move_only_options.BEMAN_ANY_VIEW_OPTION()}>,
std::vector<bool>>);
static_assert(
std::constructible_from<any_view<bool,
{.reference_type = type<bool>,
.BEMAN_ANY_VIEW_OPTION() = move_only_options.BEMAN_ANY_VIEW_OPTION()}>,
std::vector<bool>>);
static_assert(
not std::constructible_from<any_view<bool,
{.reference_type = type<bool>,
.BEMAN_ANY_VIEW_OPTION() = move_only_options.BEMAN_ANY_VIEW_OPTION(),
.borrowed = true}>,
std::vector<bool>>);
static_assert(
not std::constructible_from<any_view<bool,
{.reference_type = type<bool>,
.BEMAN_ANY_VIEW_OPTION() = copyable_options.BEMAN_ANY_VIEW_OPTION(),
.borrowed = true}>,
std::vector<bool>>);

static_assert(
std::constructible_from<any_view<bool,
{.reference_type = type<bool>,
.BEMAN_ANY_VIEW_OPTION() = move_only_options.BEMAN_ANY_VIEW_OPTION(),
.borrowed = true}>,
std::vector<bool>&>);
static_assert(
std::constructible_from<any_view<bool,
{.reference_type = type<bool>,
.BEMAN_ANY_VIEW_OPTION() = copyable_options.BEMAN_ANY_VIEW_OPTION(),
.borrowed = true}>,
std::vector<bool>&>);
static_assert(std::constructible_from<any_view<bool,
{.reference_type = type<bool>,
.iterator_concept = type<std::random_access_iterator_tag>,
#if BEMAN_ANY_VIEW_USE_MOVE_ONLY()
.move_only = true
#endif
}>,
std::vector<bool>>);
static_assert(std::constructible_from<any_view<bool,
{.reference_type = type<bool>,
.sized = true,
#if BEMAN_ANY_VIEW_USE_MOVE_ONLY()
.move_only = true
#endif
}>,
std::vector<bool>>);
static_assert(std::constructible_from<any_view<bool,
{.reference_type = type<bool>,
#if BEMAN_ANY_VIEW_USE_MOVE_ONLY()
.move_only = true
#endif
}>,
std::vector<bool>>);
static_assert(not std::constructible_from<any_view<bool,
{.reference_type = type<bool>,
#if BEMAN_ANY_VIEW_USE_MOVE_ONLY()
.move_only = true,
#endif
.borrowed = true}>,
std::vector<bool>>);
static_assert(not std::constructible_from<any_view<bool,
{.reference_type = type<bool>,
#if BEMAN_ANY_VIEW_USE_MOVE_ONLY()
.move_only = true,
#endif
.borrowed = true}>,
std::vector<bool>>);

static_assert(std::constructible_from<any_view<bool,
{.reference_type = type<bool>,
#if BEMAN_ANY_VIEW_USE_MOVE_ONLY()
.move_only = true,
#endif
.borrowed = true}>,
std::vector<bool>&>);
static_assert(std::constructible_from<any_view<bool,
{.reference_type = type<bool>,
#if BEMAN_ANY_VIEW_USE_MOVE_ONLY()
.move_only = true,
#endif
.borrowed = true}>,
std::vector<bool>&>);
#endif
}

Expand Down

0 comments on commit 10c358c

Please sign in to comment.