Example:
#include <concepts>
#include <vector>
#include <fmt/ranges.h>
template <bool Copyable>
struct Vector {
std::vector<int> v;
Vector(std::initializer_list<int> elems) : v(elems) { }
Vector(Vector&&) = default;
Vector& operator=(Vector&&) = default;
Vector(Vector const&) requires Copyable = default;
Vector& operator=(Vector const&) requires Copyable = default;
auto begin() { return v.begin(); }
auto end() { return v.end(); }
};
static_assert(std::movable<Vector<false>>);
static_assert(std::movable<Vector<true>>);
static_assert(!std::copyable<Vector<false>>);
static_assert(std::copyable<Vector<true>>);
int main() {
fmt::print("{}\n", Vector<true>{1, 2, 3}); // ok [1, 2, 3]
fmt::print("{}\n", Vector<false>{1, 2, 3}); // error
}
This is because the range check for non-const ranges requires copyability and should probably just be removed (h/t @timsong-cpp):
|
template <typename T> |
|
struct has_mutable_begin_end< |
|
T, void_t<decltype(detail::range_begin(std::declval<T>())), |
|
decltype(detail::range_end(std::declval<T>())), |
|
enable_if_t<std::is_copy_constructible<T>::value>>> |
|
: std::true_type {}; |
Example:
This is because the range check for non-const ranges requires copyability and should probably just be removed (h/t @timsong-cpp):
fmt/include/fmt/ranges.h
Lines 154 to 159 in a2c05a1