C++ Library Extensions 2022.12.09
To help learn modern C++ programming
059-graph01.hpp
Go to the documentation of this file.
1#include <tpf_set.hpp>
2
3namespace tpf
4{
5 template<typename ElementType, typename NodeIndexType,
6 template<typename, typename...> class NodeContainerType,
7 template<typename, typename...> class IndexContainerType>
8 class graph
9 {
10 public:
11 using element_t = ElementType;
12 using index_t = NodeIndexType;
13 using index_container_t = IndexContainerType<index_t>; // container type for node indices
14 using node_container_t = NodeContainerType<index_container_t>; // container type for nodes
15 using element_container_t = NodeContainerType<element_t>; // container type for node values
16
17 using ref_element_container_t = NodeContainerType<std::reference_wrapper<element_t>>;
18 using const_ref_element_container_t = NodeContainerType<std::reference_wrapper<const element_t>>;
19
20 using node_ref_t = std::tuple<ElementType&, index_container_t&>;
21 using const_node_ref_t = std::tuple<const ElementType&, const index_container_t&>;
22
23 using node_info_t = std::tuple<const ElementType&, const_ref_element_container_t>;
24
25 private:
26
27 node_container_t m_nodes; // container for node list
28 element_container_t m_values; // container for each node's value
29
30 public:
31
32 auto begin() { return this->m_nodes.begin(); }
33 auto end() { return this->m_nodes.end(); }
34
35 auto cbegin() { return this->m_nodes.cbegin(); }
36 auto cend() { return this->m_nodes.cend(); }
37
38 bool empty() const { return this->m_nodes.empty(); }
39
40 decltype(auto) adjacency_node_list(size_t node_index)
41 {
42 return tpf::element<node_container_t&>(m_nodes, node_index);
43 }
44
45 decltype(auto) adjacency_node_list(size_t node_index) const
46 {
47 return tpf::element<const node_container_t&>(m_nodes, node_index);
48 }
49
50 const node_container_t& node_lists() const { return this->m_nodes; }
51 const element_container_t& values() const { return this->m_values; }
52
53 auto adjacent_node_values(size_t node_index)
54 {
56 auto indices = tpf::element<node_container_t&>(m_nodes, node_index);
57
58 for(auto& idx: indices)
59 {
60 auto& value = tpf::element<element_container_t&>(m_values, idx);
61 elements.emplace_back(std::ref(value));
62 }
63
64 return elements;
65 }
66
67 auto adjacent_node_values(size_t node_index) const
68 {
70 auto indices = tpf::element<const node_container_t&>(m_nodes, node_index);
71
72 for(auto& idx: indices)
73 {
74 auto& value = tpf::element<const element_container_t&>(m_values, idx);
75 elements.emplace_back(std::cref(value));
76 }
77
78 return elements;
79 }
80
81 decltype(auto) node_value(size_t node_index)
82 {
83 return tpf::element<element_container_t&>(m_values, node_index);
84 }
85
86 decltype(auto) node_value(size_t node_index) const
87 {
88 return tpf::element<const element_container_t&>(m_values, node_index);
89 }
90
91 node_info_t node_info(size_t node_index) const
92 {
94 auto indices = tpf::element<const node_container_t&>(m_nodes, node_index);
95
96 for(auto& idx: indices)
97 {
98 auto& value = tpf::element<const element_container_t&>(m_values, idx);
99 elements.emplace_back(std::cref(value));
100 }
101
102 return { node_value(node_index), std::move(elements) };
103 }
104
105
106 graph() = default;
107
108 size_t size() { return this->m_nodes.size(); }
109
110 template<typename EleType, typename Type, typename... Types>
111 void emplace_back(EleType&& value, Type&& index0, Types&&... indices)
112 {
113 auto v = tpf::make_random_access_container<IndexContainerType>((NodeIndexType)std::forward<Type>(index0),
114 (NodeIndexType)std::forward<Types>(indices)...);
116
117 this->m_nodes.emplace_back(std::move(v));
118 this->m_values.emplace_back(std::forward<EleType>(value));
119 }
120
121 auto operator[](size_t node_index)
122 {
123 return node_ref_t{ tpf::element<element_container_t&>(this->m_values, node_index),
124 tpf::element<node_container_t&>(this->m_nodes, node_index) };
125 }
126
127 auto operator[](size_t node_index) const
128 {
129 return const_node_ref_t{ tpf::element<const element_container_t&>(this->m_values, node_index),
130 tpf::element<const node_container_t&>(this->m_nodes, node_index) };
131 }
132
134 {
135 if(g.m_nodes.empty())
136 {
137 os << "--------\n";
138 os << " empty \n";
139 os << "--------\n";
140
141 return os;
142 }
143
144 auto last_itr = g.m_nodes.cend();
145
146 os << "--------\n";
147
149
150 size_t index = 0;
151
152 for(auto itr = g.m_nodes.cbegin(); itr != g.m_nodes.cend(); ++itr)
153 os << std::setw(3) << index << " - ("
154 << tpf::element<const element_container_t&>(g.m_values, index++)<<") " << *itr << "\n";
155
156 os << "--------";
157
158 return os;
159 }
160 };
161
162 template<typename ElementType = int, typename NodeIndexType = int,
163 template<typename, typename...> class NodeContainerType = std::list,
164 template<typename, typename...> class IndexContainerType = std::vector>
166
167} // end of namespace tpf
reference_wrapper< Type > ref(Type &val) noexcept
std::tuple< const ElementType &, const_ref_element_container_t > node_info_t
Definition: 059-graph01.hpp:23
const element_container_t & values() const
Definition: 059-graph01.hpp:51
bool empty() const
Definition: 059-graph01.hpp:38
size_t size()
NodeContainerType< std::reference_wrapper< element_t > > ref_element_container_t
Definition: 059-graph01.hpp:17
graph()=default
decltype(auto) node_value(size_t node_index) const
Definition: 059-graph01.hpp:86
auto adjacent_node_values(size_t node_index) const
Definition: 059-graph01.hpp:67
std::tuple< const ElementType &, const index_container_t & > const_node_ref_t
Definition: 059-graph01.hpp:21
decltype(auto) adjacency_node_list(size_t node_index)
Definition: 059-graph01.hpp:40
NodeIndexType index_t
Definition: 059-graph01.hpp:12
decltype(auto) adjacency_node_list(size_t node_index) const
Definition: 059-graph01.hpp:45
auto operator[](size_t node_index)
void emplace_back(EleType &&value, Type &&index0, Types &&... indices)
NodeContainerType< std::reference_wrapper< const element_t > > const_ref_element_container_t
Definition: 059-graph01.hpp:18
NodeContainerType< index_container_t > node_container_t
Definition: 059-graph01.hpp:14
auto operator[](size_t node_index) const
std::tuple< ElementType &, index_container_t & > node_ref_t
Definition: 059-graph01.hpp:20
auto begin()
Definition: 059-graph01.hpp:32
decltype(auto) node_value(size_t node_index)
Definition: 059-graph01.hpp:81
friend tpf::sstream & operator<<(tpf::sstream &os, const graph &g)
auto end()
Definition: 059-graph01.hpp:33
auto cbegin()
Definition: 059-graph01.hpp:35
auto adjacent_node_values(size_t node_index)
Definition: 059-graph01.hpp:53
auto cend()
Definition: 059-graph01.hpp:36
NodeContainerType< element_t > element_container_t
Definition: 059-graph01.hpp:15
const node_container_t & node_lists() const
Definition: 059-graph01.hpp:50
node_info_t node_info(size_t node_index) const
Definition: 059-graph01.hpp:91
IndexContainerType< index_t > index_container_t
Definition: 059-graph01.hpp:13
types::enable_if_container_type_t< ContainerType< EleType, Types... >, bool > sort_in_place(ContainerType< EleType, Types... > &container, sort_order order=sort_order::ascending, sort_method method=sort_method::size)
Definition: tpf_set.hpp:376
Includes subnamespace conversion.
Definition: 31-visit.cpp:7
Implements set operations.