Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions D3128_Algorithms/tex/algorithms.tex
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,12 @@ \subsection{Edge Weight Concepts}
is_arithmetic_v<DistanceValue> &&
strict_weak_order<Compare, DistanceValue, DistanceValue> &&
assignable_from<add_lvalue_reference_t<DistanceValue>,
invoke_result_t<Combine, DistanceValue, invoke_result_t<WF, edge_reference_t<G>>>>;
invoke_result_t<Combine, DistanceValue, invoke_result_t<WF, edge_t<G>>>>;

// For exposition only
template <class G, class WF, class DistanceValue>
concept edge_weight_function = // e.g. weight(uv)
is_arithmetic_v<invoke_result_t<WF, edge_reference_t<G>>> &&
is_arithmetic_v<invoke_result_t<WF, edge_t<G>>> &&
basic_edge_weight_function<G,
WF,
DistanceValue,
Expand Down
40 changes: 26 additions & 14 deletions D3130_Container_Interface/src/concepts_adj_list.hpp
Original file line number Diff line number Diff line change
@@ -1,21 +1,33 @@
// For exposition only

template <class G>
concept adjacency_list = vertex_range<G> && //
targeted_edge_range<G> && //
targeted_edge<G>;
template <class G>
concept adjacency_list = requires(G& g, vertex_t<G> u) {
{ vertices(g) } -> vertex_range<G>;
{ out_edges(g, u) } -> out_edge_range<G>;
};

template <class G>
concept index_adjacency_list = adjacency_list<G> &&
index_vertex_range<G>;

template <class G>
concept index_adjacency_list = index_vertex_range<G> && //
targeted_edge_range<G> && //
targeted_edge<G>;
template <class G>
concept bidirectional_adjacency_list =
adjacency_list<G> &&
requires(G& g, vertex_t<G> u, in_edge_t<G> ie) {
{ in_edges(g, u) } -> in_edge_range<G>;
{ source_id(g, ie) } -> convertible_to<vertex_id_t<G>>;
};

template <class G>
concept index_bidirectional_adjacency_list =
bidirectional_adjacency_list<G> &&
index_vertex_range<G>;

template <class G>
concept sourced_adjacency_list = vertex_range<G> && //
targeted_edge_range<G> && //
sourced_targeted_edge<G>;
concept mapped_adjacency_list = adjacency_list<G> &&
mapped_vertex_range<G>;

template <class G>
concept sourced_index_adjacency_list = index_vertex_range<G> && //
targeted_edge_range<G> && //
sourced_targeted_edge<G>;
concept mapped_bidirectional_adjacency_list =
bidirectional_adjacency_list<G> &&
mapped_vertex_range<G>;
21 changes: 0 additions & 21 deletions D3130_Container_Interface/src/concepts_basic_adj_list.hpp

This file was deleted.

21 changes: 7 additions & 14 deletions D3130_Container_Interface/src/concepts_edges.hpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
// For exposition only

template <class G>
concept targeted_edge = requires(G&& g, edge_reference_t<G> uv) {
target(g, uv);
target_id(g, uv);
};

template <class G>
concept sourced_edge = requires(G&& g, edge_reference_t<G> uv) {
source(g, uv);
source_id(g, uv);
};

template <class G>
concept sourced_targeted_edge = targeted_edge<G> && sourced_edge<G>;
template <class G, class E>
concept edge = requires(G& g, const E& e) {
source_id(g, e);
source(g, e);
target_id(g, e);
target(g, e);
};
21 changes: 0 additions & 21 deletions D3130_Container_Interface/src/concepts_edges_before.hpp

This file was deleted.

14 changes: 7 additions & 7 deletions D3130_Container_Interface/src/concepts_target_edge_range.hpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// For exposition only

template <class G>
concept targeted_edge_range =
basic_targeted_edge_range<G> &&
requires(G&& g, vertex_reference_t<G> u, vertex_id_t<G> uid) {
{ edges(g, u) } -> forward_range;
{ edges(g, uid) } -> forward_range; // implies call to find\_vertex(g,uid)
};
template <class R, class G>
concept out_edge_range = forward_range<R> &&
edge<G, range_value_t<R>>;

template <class R, class G>
concept in_edge_range = forward_range<R> &&
edge<G, range_value_t<R>>;
34 changes: 24 additions & 10 deletions D3130_Container_Interface/src/concepts_vertex_range.hpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
// For exposition only

template <class G>
concept _common_vertex_range = ranges::sized_range<vertex_range_t<G>> &&
requires(G&& g, vertex_iterator_t<G> ui) { vertex_id(g, ui); };
template <class G, class V>
concept vertex = requires(G& g, const V& u, const vertex_id_t<G>& uid) {
vertex_id(g, u);
find_vertex(g, uid);
};

template <class R, class G>
concept vertex_range = forward_range<R> &&
sized_range<R> &&
vertex<G, remove_cvref_t<range_value_t<R>>>;

template <class G>
concept vertex_range = _common_vertex_range<vertex_range_t<G>> &&
forward_range<vertex_range_t<G>>;
template <class G>
concept index_vertex_range =
integral<vertex_id_t<G>> &&
integral<typename vertex_range_t<G>::storage_type> &&
requires(G& g) {
{ vertices(g) } -> vertex_range<G>;
};

template <class G>
concept index_vertex_range = _common_vertex_range<vertex_range_t<G>> &&
random_access_range<vertex_range_t<G>> &&
integral<vertex_id_t<G>>;
template <class G>
concept mapped_vertex_range =
!index_vertex_range<G> &&
requires(G& g, const vertex_id_t<G>& uid) {
{ vertices(g) } -> forward_range;
find_vertex(g, uid);
};
194 changes: 73 additions & 121 deletions D3130_Container_Interface/src/descriptor.hpp
Original file line number Diff line number Diff line change
@@ -1,129 +1,81 @@
template <forward_iterator InnerIter>
class descriptor {
public:
using inner_iterator = InnerIter;
using inner_value_type = iter_value_t<inner_iterator>;
// preserve inner value constness based on inner\_iterator
using inner_reference =
conditional_t<is_const_v<remove_reference_t<decltype(*declval<inner_iterator>())>>,
add_lvalue_reference_t<std::add_const_t<inner_value_type>>,
add_lvalue_reference_t<inner_value_type>>;
using inner_pointer =
conditional_t<is_const_v<remove_reference_t<decltype(*declval<inner_iterator>())>>,
add_pointer_t<std::add_const_t<inner_value_type>>,
add_pointer_t<inner_value_type>>;

// Determine if this an index-based or iterator-based descriptor
using id_type = ptrdiff_t;
using value_type = conditional_t<random_access_iterator<inner_iterator>, id_type, inner_iterator>;

// Honor the const/non-const contract for the value type
using pointer = std::add_pointer_t<value_type>;
using const_pointer = std::add_pointer_t<std::add_const_t<value_type>>;

using reference = std::add_lvalue_reference_t<value_type>;
using const_reference = std::add_lvalue_reference_t<std::add_const_t<value_type>>;

using difference_type = std::iter_difference_t<inner_iterator>;

constexpr descriptor() = default;
constexpr descriptor(const descriptor&) = default;
constexpr descriptor(descriptor&&) = default;
constexpr ~descriptor() noexcept = default;

constexpr descriptor(InnerIter first, InnerIter it) : begin_(first);
constexpr descriptor(InnerIter first, ptrdiff_t id);

// for testing
template <forward_range R>
requires is_convertible_v<iterator_t<R>, InnerIter>
constexpr descriptor(R& r, inner_iterator it).

template <forward_range R>
requires is_convertible_v<iterator_t<R>, InnerIter>
constexpr descriptor(R& r, std::ptrdiff_t id = 0);

constexpr descriptor& operator=(const descriptor&) = default;
constexpr descriptor& operator=(descriptor&&) = default;

// Properies
// For exposition only

struct out_edge_tag {};
struct in_edge_tag {};

template <class VertexIter>
class vertex_descriptor {
public:
constexpr value_type& value() const noexcept;
using iterator_type = VertexIter;
using value_type = iter_value_t<VertexIter>;

// index for random-access, iterator for bidirectional (for exposition only)
using storage_type =
conditional_t<random_access_iterator<VertexIter>, size_t, VertexIter>;

constexpr vertex_descriptor() = default;
constexpr explicit vertex_descriptor(storage_type val) noexcept;

constexpr inner_iterator get_inner_iterator() const;
// Properties
constexpr storage_type value() const noexcept;
constexpr decltype(auto) vertex_id() const noexcept;

[[nodiscard]] constexpr inner_reference inner_value() noexcept;
[[nodiscard]] constexpr inner_reference inner_value() const noexcept;
template <class Container>
constexpr decltype(auto) underlying_value(Container& c) const noexcept;

// Operators
template <class Container>
constexpr decltype(auto) inner_value(Container& c) const noexcept;

// Iterator-like interface
constexpr vertex_descriptor& operator++() noexcept;
constexpr vertex_descriptor operator++(int) noexcept;

// Comparison
constexpr auto operator<=>(const vertex_descriptor&) const noexcept = default;
constexpr bool operator==(const vertex_descriptor&) const noexcept = default;

private:
storage_type storage_ = storage_type(); // for exposition only
};


template <class EdgeIter,
class VertexIter,
class EdgeDirection = out_edge_tag>
class edge_descriptor {
public:
//
// dereference
//
// Note: range concept requirement: decltype(*descriptor) == value\_type\&
[[nodiscard]] constexpr reference operator*() noexcept;
[[nodiscard]] constexpr const_reference operator*() const noexcept;

[[nodiscard]] constexpr pointer operator->() noexcept;
[[nodiscard]] constexpr const_pointer operator->() const noexcept;

//
// operator ++ += +
//
constexpr descriptor& operator++();
constexpr descriptor operator++(int);

constexpr descriptor& operator+=(iter_difference_t<inner_iterator> n)
requires random_access_iterator<inner_iterator>;
constexpr descriptor operator+(iter_difference_t<inner_iterator> n) const
requires random_access_iterator<inner_iterator>;

//
// operator -- -= -
//
constexpr descriptor& operator--()
requires bidirectional_iterator<inner_iterator>;
constexpr descriptor operator--(int)
requires bidirectional_iterator<inner_iterator>;

constexpr descriptor& operator-=(iter_difference_t<inner_iterator> n)
requires random_access_iterator<inner_iterator>;
constexpr descriptor operator-(iter_difference_t<inner_iterator> n) const
requires random_access_iterator<inner_iterator>;

template <class InnerIter2>
constexpr iter_difference_t<inner_iterator> operator-(const descriptor<InnerIter2>& rhs) const
requires random_access_iterator<inner_iterator>;

//
// operator []
//
constexpr inner_reference operator[](iter_difference_t<inner_iterator> n) const
requires random_access_iterator<inner_iterator>;

//
// operators ==, <=>
//
constexpr bool operator==(const descriptor& rhs) const noexcept;

template <forward_iterator InnerIter2>
requires std::equality_comparable_with<InnerIter, InnerIter2>
constexpr bool operator==(const descriptor<InnerIter2>& rhs) const noexcept;

// for testing; useful in general?
template <forward_iterator InnerIter2>
requires std::equality_comparable_with<InnerIter, InnerIter2>
constexpr bool operator==(const InnerIter2& rhs) const noexcept;

constexpr auto operator<=>(const descriptor& rhs) const noexcept
requires std::integral<value_type> || std::random_access_iterator<inner_iterator>;

template <random_access_iterator InnerIter2>
requires std::three_way_comparable_with<InnerIter, InnerIter2> &&
(std::integral<value_type> || random_access_iterator<inner_iterator>)
constexpr auto operator<=>(const descriptor<InnerIter2>& rhs) const noexcept;
using edge_iterator_type = EdgeIter;
using vertex_iterator_type = VertexIter;
using vertex_desc = vertex_descriptor<VertexIter>;
using edge_direction = EdgeDirection;

static constexpr bool is_in_edge = is_same_v<EdgeDirection, in_edge_tag>;
static constexpr bool is_out_edge = is_same_v<EdgeDirection, out_edge_tag>;

// index for random-access, iterator for forward (for exposition only)
using edge_storage_type =
conditional_t<random_access_iterator<EdgeIter>, size_t, EdgeIter>;

constexpr edge_descriptor() = default;
constexpr edge_descriptor(edge_storage_type edge_val,
vertex_desc source) noexcept;

// Properties
constexpr edge_storage_type value() const noexcept;
constexpr vertex_desc source() const noexcept;
constexpr decltype(auto) source_id() const noexcept;

template <class VertexData>
constexpr auto target_id(const VertexData& vd) const noexcept;

template <class VertexData>
constexpr decltype(auto) underlying_value(VertexData& vd) const noexcept;

// Comparison
constexpr auto operator<=>(const edge_descriptor&) const noexcept = default;
constexpr bool operator==(const edge_descriptor&) const noexcept = default;

private:
value_type value_ = value_type(); // index or iterator (for exposition only)
inner_iterator begin_ = inner_iterator(); // begin of the inner range (for exposition only)
edge_storage_type edge_storage_ = edge_storage_type(); // for exposition only
vertex_desc source_ = vertex_desc(); // for exposition only
};
Loading
Loading