#ifndef BASE_CONTAINERS_ADAPTERS_INTERNAL_H_
#define BASE_CONTAINERS_ADAPTERS_INTERNAL_H_
#include <stddef.h>
#include <iterator>
#include <ranges>
#include <utility>
#include "base/compiler_specific.h"
#include "base/memory/raw_ptr_exclusion.h"
namespace base::internal {
template <typename Range>
class RangeOfRvaluesAdapter;
template <typename Range>
class ReversedAdapter;
}
template <typename Range>
inline constexpr bool std::ranges::enable_borrowed_range<
base::internal::RangeOfRvaluesAdapter<Range>> =
std::ranges::borrowed_range<Range>;
template <typename Range>
inline constexpr bool
std::ranges::enable_borrowed_range<base::internal::ReversedAdapter<Range>> =
std::ranges::borrowed_range<Range>;
namespace base::internal {
template <typename Range>
class RangeOfRvaluesAdapter {
public:
explicit RangeOfRvaluesAdapter(Range&& range LIFETIME_BOUND)
: range_(std::forward<Range>(range)) {}
RangeOfRvaluesAdapter(const RangeOfRvaluesAdapter&) = default;
RangeOfRvaluesAdapter& operator=(const RangeOfRvaluesAdapter&) = delete;
auto size() const
requires std::ranges::sized_range<Range>
{
return std::ranges::size(range_);
}
auto begin() { return std::make_move_iterator(std::ranges::begin(range_)); }
auto end() { return std::make_move_iterator(std::ranges::end(range_)); }
private:
RAW_PTR_EXCLUSION Range&& range_;
};
template <typename Range>
class ReversedAdapter {
public:
explicit ReversedAdapter(Range&& range LIFETIME_BOUND)
: range_(std::forward<Range>(range)) {}
ReversedAdapter(const ReversedAdapter&) = default;
ReversedAdapter& operator=(const ReversedAdapter&) = delete;
auto begin() { return std::rbegin(range_); }
auto begin() const { return std::rbegin(range_); }
auto cbegin() const { return std::crbegin(range_); }
auto end() { return std::rend(range_); }
auto end() const { return std::rend(range_); }
auto cend() const { return std::crend(range_); }
auto size() const
requires std::ranges::sized_range<Range>
{
return std::ranges::size(range_);
}
private:
RAW_PTR_EXCLUSION Range&& range_;
};
}
#endif