-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDistributor.h
More file actions
92 lines (77 loc) · 2.26 KB
/
Copy pathDistributor.h
File metadata and controls
92 lines (77 loc) · 2.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#pragma once
#include <vector>
#include <algorithm>
namespace Utility
{
class Indexer
{
struct Pair
{
Pair(size_t index = 0)
: index_(index)
, total_(0)
{}
struct Comparator
{
bool operator() ( Pair const& lhs, Pair const& rhs )
{
return rhs.total_ < lhs.total_;
}
};
size_t index_;
size_t total_;
};
public:
Indexer(size_t size)
: array_(size)
{
size_t _ctr(0);
for ( auto& _item : array_ ) { _item.index_ = _ctr++; }
std::make_heap( array_.begin(), array_.end(), Pair::Comparator() );
}
size_t operator() ( size_t size )
{
// extract smallest total
std::pop_heap( array_.begin(), array_.end(), Pair::Comparator() );
// save index
size_t _index(array_.back().index_);
// update and reheap
array_.back().total_ += size;
std::push_heap( array_.begin(), array_.end(), Pair::Comparator() );
return _index;
}
template<typename Action>
void for_each( Action&& action ) const
{
for ( auto const& _item : array_ ) { action( _item.index_, _item.total_ ); }
}
private:
std::vector<Pair> array_;
};
template<typename ValueType>
class Distributor
{
using List = std::vector<ValueType>;
using Lists = std::vector<List>;
public:
Distributor(size_t size)
: indexer_(size)
, lists_(size)
{}
void assign( ValueType const& value, size_t size )
{
lists_[indexer_( size )].push_back( value );
}
template<typename Action>
void for_each( Action&& action ) const
{
indexer_.for_each( [&action, this]( size_t index, size_t total )
{
action( total, lists_[index] );
} );
}
private:
Indexer indexer_;
Lists lists_;
};
} // namespace Utility