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 <iostream>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
#include <boost/container_hash/hash.hpp>
|
#include <boost/container_hash/hash.hpp>
|
||||||
|
|
||||||
|
|
@ -122,33 +123,70 @@ public:
|
||||||
return &cs[1];
|
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;
|
std::string_view remaining;
|
||||||
size_t slash;
|
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)
|
Iterator(std::string_view remaining)
|
||||||
: remaining(remaining)
|
: remaining(remaining)
|
||||||
, slash(remaining.find('/'))
|
, slash(remaining.find('/'))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const Iterator & x) const
|
|
||||||
{
|
|
||||||
return remaining.data() != x.remaining.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const Iterator & x) const
|
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);
|
return remaining.substr(0, slash);
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator++()
|
pointer_type operator->() const
|
||||||
|
{
|
||||||
|
return PointerProxy(**this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator & operator++()
|
||||||
{
|
{
|
||||||
if (slash == remaining.npos)
|
if (slash == remaining.npos)
|
||||||
remaining = remaining.substr(remaining.size());
|
remaining = remaining.substr(remaining.size());
|
||||||
|
|
@ -156,9 +194,19 @@ public:
|
||||||
remaining = remaining.substr(slash + 1);
|
remaining = remaining.substr(slash + 1);
|
||||||
slash = remaining.find('/');
|
slash = remaining.find('/');
|
||||||
}
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator operator++(int)
|
||||||
|
{
|
||||||
|
auto tmp = *this;
|
||||||
|
++*this;
|
||||||
|
return tmp;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static_assert(std::forward_iterator<Iterator>);
|
||||||
|
|
||||||
Iterator begin() const
|
Iterator begin() const
|
||||||
{
|
{
|
||||||
return Iterator(rel());
|
return Iterator(rel());
|
||||||
|
|
@ -265,6 +313,8 @@ public:
|
||||||
friend std::size_t hash_value(const CanonPath &);
|
friend std::size_t hash_value(const CanonPath &);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static_assert(std::ranges::forward_range<CanonPath>);
|
||||||
|
|
||||||
std::ostream & operator<<(std::ostream & stream, const CanonPath & path);
|
std::ostream & operator<<(std::ostream & stream, const CanonPath & path);
|
||||||
|
|
||||||
inline std::size_t hash_value(const CanonPath & path)
|
inline std::size_t hash_value(const CanonPath & path)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue