10 #ifndef ICARUSALG_UTILITIES_SIMPLECLUSTERING_H
11 #define ICARUSALG_UTILITIES_SIMPLECLUSTERING_H
17 #include <type_traits>
71 typename KeyOp,
typename CmpOp,
typename RefOp,
typename KeySortOp
75 KeyOp keyFunc, CmpOp sameGroup, RefOp objRef, KeySortOp keySort
79 template <
typename Coll,
typename KeyOp,
typename CmpOp,
typename KeySortOp>
81 (Coll
const& objs, KeyOp keyFunc, CmpOp sameGroup, KeySortOp keySort);
92 namespace util::details {
94 template <std::
size_t I,
typename KeySort>
100 template <
typename A,
typename B>
102 {
return sorter(std::forward<A>(
a), std::forward<B>(b)); }
106 template <std::
size_t I,
typename KeySort>
108 {
return { keySort }; }
116 typename KeyOp,
typename CmpOp,
typename RefOp,
typename KeySortOp
120 KeyOp keyFunc, CmpOp sameGroup, RefOp objRef, KeySortOp keySort
137 using Object_t =
typename Coll::value_type;
138 using ObjectRef_t = std::decay_t<decltype(objRef(std::declval<Object_t>()))>;
139 using Cluster_t = std::vector<ObjectRef_t>;
140 using Clusters_t = std::vector<Cluster_t>;
142 auto makeKeyAndObjRef = [keyFunc, objRef](
auto&& obj)
143 {
return std::make_pair(keyFunc(obj), objRef(obj)); };
145 using KeyAndObjRef_t = decltype(makeKeyAndObjRef(*(
util::begin(objs))));
150 std::vector<KeyAndObjRef_t> KeysAndObjRefs;
151 KeysAndObjRefs.reserve(objs.size());
160 details::makeTupleElementOp<0U>(keySort)
167 if (KeysAndObjRefs.empty())
return clusters;
172 auto startCluster = [](
auto& keyAndObjRef)
175 std::make_pair(keyAndObjRef.first, Cluster_t{ keyAndObjRef.second });
177 auto addToCluster = [](
auto&
cluster,
auto& keyAndObjRef)
178 {
cluster.second.push_back(std::move(keyAndObjRef.second)); };
180 auto currentCluster = startCluster(*iKeyAndObjRef);
181 while(++iKeyAndObjRef !=
end) {
183 if (sameGroup(iKeyAndObjRef->first, currentCluster.first)) {
184 addToCluster(currentCluster, *iKeyAndObjRef);
187 clusters.push_back(std::move(currentCluster.second));
188 currentCluster = startCluster(*iKeyAndObjRef);
192 clusters.push_back(std::move(currentCluster.second));
200 template <
typename Coll,
typename KeyOp,
typename CmpOp,
typename KeySortOp>
202 (Coll
const& objs, KeyOp keyFunc, CmpOp sameGroup, KeySortOp keySort)
205 std::move(keyFunc), std::move(sameGroup),
206 [](
auto const& obj){
return obj; },
214 #endif // ICARUSALG_UTILITIES_SIMPLECLUSTERING_H
TupleElementOp< I, KeySort > makeTupleElementOp(KeySort keySort)
auto operator()(A &&a, B &&b) const
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
auto end(FixedBins< T, C > const &) noexcept
auto clusterBy(Coll const &objs, KeyOp keyFunc, CmpOp sameGroup, RefOp objRef, KeySortOp keySort)
Performs a simple clustering.
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
TupleElementOp(KeySort keySort)