rivet
is a library to create range adaptor(closure) for the original view
type.
- header only
- single file
- cross platform
- GCC 10 or later
- MSVC 2019 or later
- clang 15(libc++ only), 16 or later
This library is only for C++20 or later.
Copy include/rivet.hpp
somewhere, reference it from your project, and include rivet.hpp
.
After inclusion of the header(rivet.hpp
), rivet::range_adaptor_base<Derived>
(for range adaptor) or rivet::range_adaptor_closure_base<Derived>
(for range adaptor closure) is used in the public inheritance by CRTP.
Example of a unique implementation of views::filter
, the range adaptor.
#include "rivet.hpp"
namespace myranges::views {
namespace detail {
// Define adapter type and CRTP
struct filter_adaptor: public rivet::range_adaptor_base<filter_adaptor> {
// Range Adoptor main process. Generates the original view.
// Always defined in `operator() const`.
template<std::ranges::viewable_range R, typename Pred>
constexpr auto operator()(R&& r, Pred&& p) const {
return std::ranges::filter_view(std::forward<R>(r), std::forward<Pred>(p));
}
// It is a hassle, but essential.
RIVET_USING_BASEOP;
};
}
// My views::filter(Range adaptor object) difinition.
inline constexpr detail::filter_adaptor filter;
}
Example of a unique implementation of views::common
, the range adaptor closure.
#include "rivet.hpp"
namespace myranges::views {
namespace detail {
// Define adapter closure type and CRTP
// In this case, specify true after the type name(common_adaptor_closure) to make it clear that it is range adaptor closure.
struct common_adaptor_closure : public rivet::range_adaptor_closure_base<common_adaptor_closure> {
// Range Adoptor Closure main process. Generates the original view.
// Always defined in `operator() const`.
template<std::ranges::viewable_range R>
constexpr auto operator()(R&& r) const {
if constexpr (std::ranges::common_range<R>) {
return std::views::all(std::forward<R>(r));
} else {
return std::ranges::common_view(std::forward<R>(r));
}
}
};
}
// My views::common(Range adaptor closure object) difinition.
inline constexpr detail::common_adaptor_closure common;
}
#include "rivet.hpp"
namespace myranges::views {
// My views::filter(Range adaptor object) difinition.
inline constexpr rivet::adaptor filter = []<std::ranges::viewable_range R, typename Pred>(R &&r, Pred &&p) {
// Range Adoptor main process. Generates the original view.
return std::ranges::filter_view(std::forward<R>(r), std::forward<Pred>(p));
};
// My views::common(Range adaptor closure object) difinition.
inline constexpr rivet::closure common = []<std::ranges::viewable_range R>(R &&r) {
// Range Adoptor Closure main process. Generates the original view.
if constexpr (std::ranges::common_range<R>) {
return std::views::all(std::forward<R>(r));
} else {
return std::ranges::common_view(std::forward<R>(r));
}
};
}
Range adaptor (closure) object can be defined by simply passing a lambda expression describing the process of generating your own view
to rivet::adaptor
(for adaptor) or rivet::closure
(for adaptor closure).