-
Notifications
You must be signed in to change notification settings - Fork 0
/
plain-containers.inl
189 lines (161 loc) · 9.03 KB
/
plain-containers.inl
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#pragma once
namespace Black
{
inline namespace Core
{
inline namespace Algorithms
{
template< typename TItem, typename TAllocator, template< typename, typename > class TStorage >
inline const bool IsItemPresent( const TStorage<TItem, TAllocator>& storage, const TItem& item )
{
return std::find( std::begin( storage ), std::end( storage ), item ) != std::end( storage );
}
template< typename TItem, size_t ARRAY_LENGTH >
inline const bool IsItemPresent( const TItem (&storage)[ ARRAY_LENGTH ], const TItem& item )
{
return std::find( std::begin( storage ), std::end( storage ), item ) != std::end( storage );
}
template< typename TItem >
inline const bool IsItemPresent( const PlainView<TItem>& storage, const TItem& item )
{
return std::find( std::begin( storage ), std::end( storage ), item ) != std::end( storage );
}
template< typename TItem >
inline const bool IsItemPresent( const PlainVector<TItem>& storage, const TItem& item )
{
return std::find( std::begin( storage ), std::end( storage ), item ) != std::end( storage );
}
template< typename TStoredItem, typename TNewItem, typename TAllocator, template< typename, typename > class TStorage >
inline const bool UniqueAdd( TStorage<TStoredItem, TAllocator>& storage, TNewItem&& item )
{
static_assert( std::is_same_v<std::decay_t<TStoredItem>, std::decay_t<TNewItem>>, "Item of such type can't be added into storage." );
CRET( IsItemPresent( storage, item ), false );
storage.emplace_back( std::forward<TNewItem>( item ) );
return true;
}
template< typename TStoredItem, typename TNewItem, typename TAllocator, template< typename, typename > class TStorage >
inline const bool UniqueAddSorted( TStorage<TStoredItem, TAllocator>& storage, TNewItem&& item )
{
static_assert( std::is_same_v<std::decay_t<TStoredItem>, std::decay_t<TNewItem>>, "Item of such type can't be added into storage." );
auto found_slot = std::upper_bound( std::begin( storage ), std::end( storage ), item );
CRET( ( found_slot > std::begin( storage ) ) && !( *std::prev( found_slot ) < item ), false );
storage.insert( found_slot, std::forward<TNewItem>( item ) );
return true;
}
template< typename TStoredItem, typename TNewItem, typename TPredicate, typename TAllocator, template< typename, typename > class TStorage >
inline const bool UniqueAddSorted( TStorage<TStoredItem, TAllocator>& storage, TNewItem&& item, const TPredicate& predicate )
{
static_assert( std::is_same_v<std::decay_t<TStoredItem>, std::decay_t<TNewItem>>, "Item of such type can't be added into storage." );
static_assert(
std::is_invocable_r_v<const bool, TPredicate, const std::decay_t<TStoredItem>&, const std::decay_t<TNewItem>&>,
"Used predicate should meets the requirement of signature `const bool ( const TStoredItem&, const TNewItem& )`."
);
auto found_slot = std::upper_bound( std::begin( storage ), std::end( storage ), item, predicate );
CRET( ( found_slot > std::begin( storage ) ) && !predicate( *std::prev( found_slot ), item ), false );
found_slot = storage.insert( found_slot, std::forward<TNewItem>( item ) );
return true;
}
template< typename TStoredItem, typename TNewItem, typename TAllocator >
inline const size_t UniqueAddIndexed( std::vector<TStoredItem, TAllocator>& storage, TNewItem&& item )
{
static_assert( std::is_same_v<std::decay_t<TStoredItem>, std::decay_t<TNewItem>>, "Item of such type can't be added into storage." );
auto found_item = std::find( std::begin( storage ), std::end( storage ), item );
CRET( found_item != std::end( storage ), std::distance( std::begin( storage ), found_item ) );
storage.emplace_back( std::forward<TNewItem>( item ) );
return storage.size() - 1;
}
template< typename TStoredItem, typename TNewItem, typename TAllocator >
inline const size_t UniqueAddSortedIndexed( std::vector<TStoredItem, TAllocator>& storage, TNewItem&& item )
{
static_assert( std::is_same_v<std::decay_t<TStoredItem>, std::decay_t<TNewItem>>, "Item of such type can't be added into storage." );
auto found_slot = std::upper_bound( std::begin( storage ), std::end( storage ), item );
CRET( ( found_slot > std::begin( storage ) ) && !( *std::prev( found_slot ) < item ), std::distance( std::begin( storage ), found_slot ) - 1 );
found_slot = storage.insert( found_slot, std::forward<TNewItem>( item ) );
return std::distance( std::begin( storage ), found_slot );
}
template< typename TStoredItem, typename TNewItem, typename TPredicate, typename TAllocator >
inline const size_t UniqueAddSortedIndexed( std::vector<TStoredItem, TAllocator>& storage, TNewItem&& item, const TPredicate& predicate )
{
static_assert( std::is_same_v<std::decay_t<TStoredItem>, std::decay_t<TNewItem>>, "Item of such type can't be added into storage." );
static_assert(
std::is_invocable_r_v<const bool, TPredicate, const std::decay_t<TStoredItem>&, const std::decay_t<TNewItem>&>,
"Used predicate should meets the requirement of signature `const bool ( const TStoredItem&, const TNewItem& )`."
);
auto found_slot = std::upper_bound( std::begin( storage ), std::end( storage ), item, predicate );
CRET( ( found_slot > std::begin( storage ) ) && !predicate( *std::prev( found_slot ), item ), std::distance( std::begin( storage ), found_slot ) - 1 );
found_slot = storage.insert( found_slot, std::forward<TNewItem>( item ) );
return std::distance( std::begin( storage ), found_slot );
}
template< typename TItem, typename TAllocator, template< typename, typename > class TStorage >
inline const bool RemoveItem( TStorage<TItem, TAllocator>& storage, const TItem& item )
{
CRET( storage.empty(), false );
auto found_item = std::find( std::begin( storage ), std::end( storage ), item );
CRET( found_item == std::end( storage ), false );
storage.erase( found_item );
return true;
}
template< typename TItem, typename TAllocator, template< typename, typename > class TStorage >
inline const bool RemoveItemSorted( TStorage<TItem, TAllocator>& storage, const TItem& item )
{
CRET( storage.empty(), false );
auto found_candidate = std::lower_bound( std::begin( storage ), std::end( storage ), item );
CRET( found_candidate == std::end( storage ), false );
CRET( ( item < *found_candidate ), false );
storage.erase( found_candidate );
return true;
}
template< typename TItem, typename TPredicate, typename TAllocator, template< typename, typename > class TStorage >
inline const bool RemoveItemSorted( TStorage<TItem, TAllocator>& storage, const TItem& item, const TPredicate& predicate )
{
CRET( storage.empty(), false );
auto found_candidate = std::lower_bound( std::begin( storage ), std::end( storage ), item, predicate );
CRET( found_candidate == std::end( storage ), false );
CRET( predicate( item, *found_candidate ), false );
storage.erase( found_candidate );
return true;
}
template< typename TItem, typename TAllocator, template< typename, typename > class TStorage >
inline void DeletePointersAndClear( TStorage<TItem*, TAllocator>& storage )
{
CRET( storage.empty() );
std::for_each( std::begin( storage ), std::end( storage ), []( TItem* item ){ delete item; } );
storage.clear();
}
template< typename TItem >
inline void DeletePointersAndClear( PlainVector<TItem*>& storage )
{
CRET( storage.IsEmpty() );
std::for_each( std::begin( storage ), std::end( storage ), []( TItem* item ){ delete item; } );
storage.clear();
}
template< typename TItem, typename TAllocator, template< typename, typename > class TStorage >
inline const size_t GetItemIndex( const TStorage<TItem, TAllocator>& storage, const TItem& item )
{
CRET( storage.empty(), Black::UNDEFINED_INDEX );
auto found_item = std::find( std::begin( storage ), std::end( storage ), item );
return ( found_item == std::end( storage ) )? Black::UNDEFINED_INDEX : std::distance( std::begin( storage ), found_item );
}
template< typename TItem, size_t ARRAY_LENGTH >
inline const size_t GetItemIndex( const TItem (&storage)[ ARRAY_LENGTH ], const TItem& item )
{
auto found_item = std::find( std::begin( storage ), std::end( storage ), item );
return ( found_item == std::end( storage ) )? Black::UNDEFINED_INDEX : std::distance( std::begin( storage ), found_item );
}
template< typename TItem >
inline const size_t GetItemIndex( const PlainView<TItem>& storage, const TItem& item )
{
CRET( storage.IsEmpty(), Black::UNDEFINED_INDEX );
auto found_item = std::find( std::begin( storage ), std::end( storage ), item );
return ( found_item == std::end( storage ) )? Black::UNDEFINED_INDEX : std::distance( std::begin( storage ), found_item );
}
template< typename TItem >
inline const size_t GetItemIndex( const PlainVector<TItem>& storage, const TItem& item )
{
CRET( storage.IsEmpty(), Black::UNDEFINED_INDEX );
auto found_item = std::find( std::begin( storage ), std::end( storage ), item );
return ( found_item == std::end( storage ) )? Black::UNDEFINED_INDEX : std::distance( std::begin( storage ), found_item );
}
}
}
}