Honeycomb  0.1
Component-Model Framework
StdUtil.h
Go to the documentation of this file.
1 // Honeycomb, Copyright (C) 2015 NewGamePlus Inc. Distributed under the Boost Software License v1.0.
2 #pragma once
3 
4 #include "Honey/Math/Numeral.h"
5 #include "Honey/Misc/Range.h"
7 
8 namespace honey
9 {
10 
12 
15 
18 template<class StdContainer>
19 int size(const StdContainer& cont) { return numeric_cast<int>(cont.size()); }
20 
22 template<class Range>
24 {
25  return honey::range(TupleIter<mt_iterOf(range),0>(begin(range)), TupleIter<mt_iterOf(range),0>(end(range)));
26 }
27 
29 template<class Range>
31 {
32  return honey::range(TupleIter<mt_iterOf(range),1>(begin(range)), TupleIter<mt_iterOf(range),1>(end(range)));
33 }
34 
36 namespace stdutil
37 {
39  template<class Iter>
40  auto reverseIterToForward(Iter&& it) -> typename mt::removeRef<decltype(--it.base())>::type
41  { return --it.base(); }
42 
44  template<class List>
45  typename List::reverse_iterator erase(List& list, const typename List::reverse_iterator& iter)
46  {
47  return typename List::reverse_iterator(list.erase(reverseIterToForward(iter)));
48  }
49 
51  template<class List>
52  typename List::iterator eraseVal(List& list, const typename List::value_type& val)
53  {
54  auto it = std::find(list.begin(), list.end(), val);
55  if (it == list.end()) return list.end();
56  return list.erase(it);
57  }
58 
60  template<class List, class T>
61  void eraseVals(List& list, const T& val)
62  {
63  auto it = list.begin();
64  while((it = std::find(it, list.end(), val)) != list.end())
65  it = list.erase(it);
66  }
67 
69  template<class MultiMap, class Key, class Val>
70  auto findVal(MultiMap& map, const Key& key, const Val& val) -> mt_iterOf(map)
71  {
72  return honey::find(range(map.equal_range(key)), [&](auto& e) { return e.second == val; });
73  }
75  template<class MultiSet, class Val>
76  auto findVal(MultiSet& set, const Val& val) -> mt_iterOf(set)
77  {
78  return honey::find(range(set.equal_range(val)), [&](auto& e) { return e == val; });
79  }
80 
82  template<class Key, class Value, template<class> class Alloc>
83  using unordered_map = std::unordered_map<Key, Value, std::hash<Key>, std::equal_to<Key>, Alloc<pair<const Key, Value>>>;
85  template<class Key, class Value, template<class> class Alloc>
86  using unordered_multimap = std::unordered_multimap<Key, Value, std::hash<Key>, std::equal_to<Key>, Alloc<pair<const Key, Value>>>;
88  template<class Key, template<class> class Alloc>
89  using unordered_set = std::unordered_set<Key, std::hash<Key>, std::equal_to<Key>, Alloc<Key>>;
91  template<class Key, template<class> class Alloc>
92  using unordered_multiset = std::unordered_multiset<Key, std::hash<Key>, std::equal_to<Key>, Alloc<Key>>;
93 }
94 
96 namespace priv
97 {
98  template<szt Arity> struct bind_fill;
99 
100  #define PARAMT(It) , class T##It
101  #define PARAM(It) , T##It&& a##It
102  #define ARG(It) , forward<T##It>(a##It)
103  #define PLACE(It) , _##It
104 
105  #define OP(It, ItMax) \
106  template<class Func ITERATE__(1,It,PARAMT)> \
107  auto operator()(Func&& f ITERATE__(1,It,PARAM)) -> \
108  decltype( bind(forward<Func>(f) ITERATE__(1,It,ARG) \
109  IFEQUAL(It,ItMax,,ITERATE__(1,PP_SUB(ItMax,It),PLACE))) ) \
110  { \
111  return bind(forward<Func>(f) ITERATE__(1,It,ARG) \
112  IFEQUAL(It,ItMax,,ITERATE__(1,PP_SUB(ItMax,It),PLACE))); \
113  } \
114 
115  #define STRUCT(It) \
116  template<> struct bind_fill<It> { ITERATE1_(0, It, OP, It) }; \
117 
118  ITERATE(0, 9, STRUCT)
119  #undef PARAMT
120  #undef PARAM
121  #undef ARG
122  #undef PLACE
123  #undef OP
124  #undef STRUCT
125 }
128 
137 template<class Func, class... Args>
138 auto bind_fill(Func&& f, Args&&... args) ->
139  decltype( priv::bind_fill<mt::funcTraits<typename mt::removeRef<Func>::type>::arity>()(forward<Func>(f), forward<Args>(args)...))
140 {
141  return priv::bind_fill<mt::funcTraits<typename mt::removeRef<Func>::type>::arity>()(forward<Func>(f), forward<Args>(args)...);
142 }
143 
145 
148 template<class T, class Ptr = T*, class ConstPtr = const T*>
150 {
151 public:
152  deref_wrap(Ptr ptr = nullptr) : _ptr(ptr) {}
153  T& operator*() { assert(_ptr); return *_ptr; }
154  const T& operator*() const { assert(_ptr); return *_ptr; }
155  T* operator->() { assert(_ptr); return _ptr; }
156  const T* operator->() const { assert(_ptr); return _ptr; }
157  operator T&() { assert(_ptr); return *_ptr; }
158  operator const T&() const { assert(_ptr); return *_ptr; }
159  bool operator==(const deref_wrap& rhs) const { return _ptr == rhs._ptr; }
160  bool operator!=(const deref_wrap& rhs) const { return !operator==(rhs); }
161  Ptr& ptr() { return _ptr; }
162  const ConstPtr& ptr() const { return reinterpret_cast<const ConstPtr&>(_ptr); }
163 private:
164  Ptr _ptr;
165 };
166 
168 
172 template<class T, class Alloc = typename DefaultAllocator<T>::type>
174 {
175 public:
176  recursive_wrap(Alloc a = Alloc()) : _ptr(new (a.allocate(1)) T, move(a)) {}
177  template<class T_>
178  recursive_wrap(T_&& t, Alloc a = Alloc()) : _ptr(new (a.allocate(1)) T(forward<T_>(t)), move(a)) {}
179  recursive_wrap(const recursive_wrap& rhs) : _ptr(new (const_cast<Alloc&>(rhs._ptr.finalizer().a).allocate(1)) T(*rhs), rhs._ptr.finalizer()) {}
180  recursive_wrap(recursive_wrap& rhs) : _ptr(new (rhs._ptr.finalizer().a.allocate(1)) T(*rhs), rhs._ptr.finalizer()) {}
181  recursive_wrap(recursive_wrap&& rhs) : _ptr(move(rhs._ptr)) {}
182 
183  template<class T_>
184  recursive_wrap& operator=(T_&& t) { **this = forward<T_>(t); return *this; }
185  recursive_wrap& operator=(const recursive_wrap& rhs) { **this = *rhs; return *this; }
186  recursive_wrap& operator=(recursive_wrap& rhs) { **this = *rhs; return *this; }
187  recursive_wrap& operator=(recursive_wrap&& rhs) { _ptr = move(rhs._ptr); return *this; }
188 
190  T& operator*() { assert(_ptr); return *_ptr; }
191  const T& operator*() const { assert(_ptr); return *_ptr; }
192  T* operator->() { assert(_ptr); return _ptr; }
193  const T* operator->() const { assert(_ptr); return _ptr; }
194  operator T&() { assert(_ptr); return *_ptr; }
195  operator const T&() const { assert(_ptr); return *_ptr; }
197  T* ptr() { return _ptr; }
198  const T* ptr() const { return _ptr; }
199 
200 private:
202 };
203 
205 template<class Subclass>
206 class Manip
207 {
208 public:
209  static bool hasInst(ios_base& ios) { return ios.pword(pword); }
210  static Subclass& inst(ios_base& ios)
211  {
212  if (!hasInst(ios)) { ios.pword(pword) = new Subclass(); ios.register_callback(&Manip::delete_, 0); }
213  return *static_cast<Subclass*>(ios.pword(pword));
214  }
215 
216 private:
217  static void delete_(ios_base::event ev, ios_base& ios, int) { if (ev == ios_base::erase_event) honey::delete_(&inst(ios)); }
218  static const int pword;
219 };
220 template<class Subclass> const int Manip<Subclass>::pword = ios_base::xalloc();
221 
223 template<class Func, class Tuple>
224 struct ManipFunc
225 {
226  template<class Func_, class Tuple_>
227  ManipFunc(Func_&& f, Tuple_&& args) : f(forward<Func_>(f)), args(forward<Tuple_>(args)) {}
228 
229  template<class Stream>
230  friend Stream& operator<<(Stream& os, const ManipFunc& manip) { manip.apply(os, mt::make_idxseq<tuple_size<Tuple>::value>()); return os; }
231  template<class Stream>
232  friend Stream& operator>>(Stream& is, const ManipFunc& manip) { manip.apply(is, mt::make_idxseq<tuple_size<Tuple>::value>()); return is; }
233 
234  template<class Stream, szt... Seq>
235  void apply(Stream& ios, mt::idxseq<Seq...>) const { f(ios, get<Seq>(args)...); }
236 
237  Func f;
238  Tuple args;
239 };
240 
242 template<class Func, class... Args>
243 inline auto manipFunc(Func&& f, Args&&... args) { return ManipFunc<Func, decltype(make_tuple(forward<Args>(args)...))>(forward<Func>(f), make_tuple(forward<Args>(args)...)); }
244 
246 
247 }
248 
ManipFunc(Func_ &&f, Tuple_ &&args)
Definition: StdUtil.h:227
T * operator->()
Definition: StdUtil.h:155
auto manipFunc(Func &&f, Args &&...args)
Helper to create a manipulator that takes arguments. eg. A manip named 'foo': auto foo(int val) { ret...
Definition: StdUtil.h:243
recursive_wrap(Alloc a=Alloc())
Definition: StdUtil.h:176
bool operator==(const deref_wrap &rhs) const
Definition: StdUtil.h:159
recursive_wrap & operator=(const recursive_wrap &rhs)
Definition: StdUtil.h:185
Wraps a pointer so that it behaves similar to a reference.
Definition: StdUtil.h:149
recursive_wrap & operator=(recursive_wrap &rhs)
Definition: StdUtil.h:186
Allows for recursive type definitions, eg. class Object : vector>.
Definition: StdUtil.h:173
bool operator!=(const deref_wrap &rhs) const
Definition: StdUtil.h:160
T * ptr()
Get the internal pointer, may be null if wrapper was moved.
Definition: StdUtil.h:197
auto findVal(MultiMap &map, const Key &key, const Val &val) -> mt_iterOf(map)
Get iterator to key with value. Returns end if not found.
Definition: StdUtil.h:70
const ConstPtr & ptr() const
Definition: StdUtil.h:162
List::reverse_iterator erase(List &list, const typename List::reverse_iterator &iter)
Erase using reverse iterator. Returns reverse iterator to element after erased element.
Definition: StdUtil.h:45
Iter find(Range &&, Seqs &&..., Func &&pred)
Find an element in a series of sequences.
Wrapper around an iterator with tuple value type. When dereferenced returns I'th element.
Definition: Range.h:596
void delete_(T *&p)
Destruct object, free memory and set pointer to null.
Definition: Allocator.h:75
const T & operator*() const
Definition: StdUtil.h:191
static bool hasInst(ios_base &ios)
Definition: StdUtil.h:209
std::index_sequence< Ints... > idxseq
Shorthand for std::index_sequence.
Definition: Meta.h:111
auto bind_fill(Func &&f, Args &&...args) -> decltype( priv::bind_fill< mt::funcTraits< typename mt::removeRef< Func >::type >::arity >()(forward< Func >(f), forward< Args >(args)...))
Version of bind that automatically fills in placeholders for unspecified arguments.
Definition: StdUtil.h:138
std::unordered_map< Key, Value, std::hash< Key >, std::equal_to< Key >, Alloc< pair< const Key, Value >>> unordered_map
std::unordered_map with custom allocator
Definition: StdUtil.h:83
std::remove_reference< T > removeRef
Remove reference from type.
Definition: Meta.h:44
std::enable_if< mt::isIterator< Iter1 >::value, Range_< Iter1, Iter2 > >::type range(Iter1 &&first, Iter2 &&last)
Range from iterators [first, last)
Definition: Range.h:116
friend Stream & operator>>(Stream &is, const ManipFunc &manip)
Definition: StdUtil.h:232
T * operator->()
Definition: StdUtil.h:192
Helper to create a manipulator that takes arguments.
Definition: StdUtil.h:224
auto keys(Range &&range) -> Range_< TupleIter< mt_iterOf(range), 0 >, TupleIter< mt_iterOf(range), 0 >>
Create a range over the keys of a map or map iterator range.
Definition: StdUtil.h:23
T & operator*()
Definition: StdUtil.h:153
#define mt_iterOf(Range)
iterOf for values
Definition: Range.h:33
recursive_wrap & operator=(T_ &&t)
Definition: StdUtil.h:184
friend Stream & operator<<(Stream &os, const ManipFunc &manip)
Definition: StdUtil.h:230
static Subclass & inst(ios_base &ios)
Definition: StdUtil.h:210
Get function type traits.
Definition: Meta.h:227
#define assert(...)
Forwards to assert_#args. See assert_1(), assert_2().
Definition: Debug.h:24
Ptr & ptr()
Definition: StdUtil.h:161
recursive_wrap(recursive_wrap &rhs)
Definition: StdUtil.h:180
Func f
Definition: StdUtil.h:237
void eraseVals(List &list, const T &val)
Erase all occurrences of value.
Definition: StdUtil.h:61
const T * ptr() const
Definition: StdUtil.h:198
std::unordered_multiset< Key, std::hash< Key >, std::equal_to< Key >, Alloc< Key >> unordered_multiset
std::unordered_multiset with custom allocator
Definition: StdUtil.h:92
size_t szt
Size type, shorthand for size_t.
Definition: Core.h:90
auto values(Range &&range) -> Range_< TupleIter< mt_iterOf(range), 1 >, TupleIter< mt_iterOf(range), 1 >>
Create a range over the values of a map or map iterator range.
Definition: StdUtil.h:30
auto reverseIterToForward(Iter &&it) -> typename mt::removeRef< decltype(--it.base())>::type
Convert reverse iterator to forward iterator.
Definition: StdUtil.h:40
std::unordered_multimap< Key, Value, std::hash< Key >, std::equal_to< Key >, Alloc< pair< const Key, Value >>> unordered_multimap
std::unordered_multimap with custom allocator
Definition: StdUtil.h:86
#define ITERATE(Min, Max, Func)
Iterate calling Func(It, Args...) over range [Min, Max], where Min >= 0 and Max <= ITERATE_MAX...
Definition: Preprocessor.h:58
T & operator*()
Get the wrapped object.
Definition: StdUtil.h:190
const T * operator->() const
Definition: StdUtil.h:193
Iterator range. See range(Iter1&&, Iter2&&) to create.
Definition: Range.h:88
int size(const StdContainer &cont)
Safely get the size of a std container as a signed integer.
Definition: StdUtil.h:19
List::iterator eraseVal(List &list, const typename List::value_type &val)
Erase first occurrence of value. Returns iterator to next element after the erased element...
Definition: StdUtil.h:52
std::make_index_sequence< N > make_idxseq
Shorthand for std::make_index_sequence.
Definition: Meta.h:113
recursive_wrap(T_ &&t, Alloc a=Alloc())
Definition: StdUtil.h:178
const T * operator->() const
Definition: StdUtil.h:156
Base class to hold iostream manipulator state. Inherit from this class and call Subclass::inst(ios) t...
Definition: StdUtil.h:206
Tuple args
Definition: StdUtil.h:238
recursive_wrap(const recursive_wrap &rhs)
Definition: StdUtil.h:179
const T & operator*() const
Definition: StdUtil.h:154
deref_wrap(Ptr ptr=nullptr)
Definition: StdUtil.h:152
std::unordered_set< Key, std::hash< Key >, std::equal_to< Key >, Alloc< Key >> unordered_set
std::unordered_set with custom allocator
Definition: StdUtil.h:89
Pointer to a unique, non-shared, object. Finalizer is run upon destruction (deletes object by default...
Definition: SharedPtr.h:164
recursive_wrap & operator=(recursive_wrap &&rhs)
Definition: StdUtil.h:187
Global Honeycomb namespace.
void apply(Stream &ios, mt::idxseq< Seq... >) const
Definition: StdUtil.h:235
recursive_wrap(recursive_wrap &&rhs)
Definition: StdUtil.h:181
OutSeq && map(Range &&, Seqs &&..., OutSeq &&, Func &&)
Transform a series of sequences into an output.