mirror of
https://github.com/NixOS/nix.git
synced 2025-11-18 08:19:35 +01:00
Merge pull request #14568 from NixOS/proper-range-canon-path
libutil: Make CanonPath a proper range
This commit is contained in:
commit
1f2a994fb9
1 changed files with 59 additions and 9 deletions
|
|
@ -8,6 +8,7 @@
|
|||
#include <iostream>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <ranges>
|
||||
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
|
||||
|
|
@ -122,33 +123,70 @@ public:
|
|||
return &cs[1];
|
||||
}
|
||||
|
||||
struct Iterator
|
||||
class Iterator
|
||||
{
|
||||
/**
|
||||
* Helper class with overloaded operator-> for "drill-down" behavior.
|
||||
* This was a "temporary" string_view doesn't have to be stored anywhere.
|
||||
*/
|
||||
class PointerProxy
|
||||
{
|
||||
std::string_view segment;
|
||||
|
||||
public:
|
||||
PointerProxy(std::string_view segment_)
|
||||
: segment(segment_)
|
||||
{
|
||||
}
|
||||
|
||||
const std::string_view * operator->() const
|
||||
{
|
||||
return &segment;
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
using value_type = std::string_view;
|
||||
using reference_type = const std::string_view;
|
||||
using pointer_type = PointerProxy;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
|
||||
std::string_view remaining;
|
||||
size_t slash;
|
||||
|
||||
/**
|
||||
* Dummy default constructor required for forward iterators. Doesn't return
|
||||
* a usable iterator.
|
||||
*/
|
||||
Iterator()
|
||||
: remaining()
|
||||
, slash(0)
|
||||
{
|
||||
}
|
||||
|
||||
Iterator(std::string_view remaining)
|
||||
: remaining(remaining)
|
||||
, slash(remaining.find('/'))
|
||||
{
|
||||
}
|
||||
|
||||
bool operator!=(const Iterator & x) const
|
||||
{
|
||||
return remaining.data() != x.remaining.data();
|
||||
}
|
||||
|
||||
bool operator==(const Iterator & x) const
|
||||
{
|
||||
return !(*this != x);
|
||||
return remaining.data() == x.remaining.data();
|
||||
}
|
||||
|
||||
const std::string_view operator*() const
|
||||
reference_type operator*() const
|
||||
{
|
||||
return remaining.substr(0, slash);
|
||||
}
|
||||
|
||||
void operator++()
|
||||
pointer_type operator->() const
|
||||
{
|
||||
return PointerProxy(**this);
|
||||
}
|
||||
|
||||
Iterator & operator++()
|
||||
{
|
||||
if (slash == remaining.npos)
|
||||
remaining = remaining.substr(remaining.size());
|
||||
|
|
@ -156,9 +194,19 @@ public:
|
|||
remaining = remaining.substr(slash + 1);
|
||||
slash = remaining.find('/');
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Iterator operator++(int)
|
||||
{
|
||||
auto tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(std::forward_iterator<Iterator>);
|
||||
|
||||
Iterator begin() const
|
||||
{
|
||||
return Iterator(rel());
|
||||
|
|
@ -265,6 +313,8 @@ public:
|
|||
friend std::size_t hash_value(const CanonPath &);
|
||||
};
|
||||
|
||||
static_assert(std::ranges::forward_range<CanonPath>);
|
||||
|
||||
std::ostream & operator<<(std::ostream & stream, const CanonPath & path);
|
||||
|
||||
inline std::size_t hash_value(const CanonPath & path)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue