fork download
  1. #ifndef COMMON_ALGORITHM_FOREACH_H
  2. #define COMMON_ALGORITHM_FOREACH_H
  3.  
  4. #include <memory>
  5.  
  6. /*
  7. Calls the function 'callback' on every element in the container.
  8.  
  9. Example usage:
  10.  
  11. std::vector<Element> array;
  12. ForEach(array, DoSomething);
  13.  
  14. Or, pass arguments in:
  15.  
  16. ForEach(array, DoSomething, 17, "Text");
  17. */
  18.  
  19. //Takes a container and passes each element to a lambda or function.
  20. //Version for functors or non-generic lambdas (i.e. lambdas with capture lists).
  21. template<typename ContainerType, typename CallbackFunc, typename ...Args>
  22. void ForEach(ContainerType &container, const CallbackFunc &callback, Args&& ...args)
  23. {
  24. for(auto &element : container)
  25. {
  26. callback(element, args...);
  27. }
  28. }
  29.  
  30. //Const version, for functors and lambdas.
  31. template<typename ContainerType, typename CallbackFunc, typename ...Args>
  32. void ForEach(const ContainerType &container, CallbackFunc callback, Args&& ...args)
  33. {
  34. for(auto &element : container)
  35. {
  36. callback(element, args...);
  37. }
  38. }
  39.  
  40. //============================================================================
  41.  
  42. /*
  43. Calls the member-function 'member_func' on every element in the container.
  44.  
  45. Example usage:
  46.  
  47. std::vector<Element> array;
  48. ForEach(array, &Element::DoSomething);
  49.  
  50. Or, pass arguments in:
  51.  
  52. ForEach(array, &Element::DoSomething, 17, "Text");
  53. */
  54.  
  55. //Calls the member-function 'member_func' on every element in the container, optionally passing in arguments.
  56. template<typename ContainerType, typename ElementType, typename ...MembFuncArgs, typename ...ParamArgs>
  57. void ForEach(ContainerType &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
  58. {
  59. for(auto &element : container)
  60. {
  61. element.*member_func(args...);
  62. }
  63. }
  64.  
  65. //Const version of 'ForEach()' where you can pass arguments into the member-function call.
  66. template<typename ContainerType, typename ElementType, typename ...MembFuncArgs, typename ...ParamArgs>
  67. void ForEach(const ContainerType &container, void (ElementType::*member_func)(MembFuncArgs...) const, ParamArgs&& ...args)
  68. {
  69. for(const auto &element : container)
  70. {
  71. (element.*member_func)(args...);
  72. }
  73. }
  74.  
  75. //Calls the member-function 'member_func' on every element in the container, optionally passing in arguments.
  76. //Also, returns true if any of the member-functions return true.
  77. template<typename ContainerType, typename ElementType, typename ...MembFuncArgs, typename ...ParamArgs>
  78. bool ForEach_Return(ContainerType &container, bool (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
  79. {
  80. bool result = false;
  81. for(auto &element : container)
  82. {
  83. result = (result || (element.*member_func)(args...));
  84. }
  85.  
  86. return result;
  87. }
  88.  
  89. //Const version.
  90. template<typename ContainerType, typename ElementType, typename ...MembFuncArgs, typename ...ParamArgs>
  91. bool ForEach_Return(const ContainerType &container, bool (ElementType::*member_func)(MembFuncArgs...) const, ParamArgs&& ...args)
  92. {
  93. bool result = false;
  94. for(const auto &element : container)
  95. {
  96. result = (result || (element.*member_func)(args...));
  97. }
  98.  
  99. return result;
  100. }
  101.  
  102. //============================================================================
  103.  
  104. //Wrappers for std::unique_ptr and std::shared_ptr, with callback-function calls.
  105. template<typename Container, typename CallbackFunc, typename ...Args>
  106. void priv_ForEachPtr_impl_forSharedOrUniquePtrsCallbackFunc(Container &container, CallbackFunc callback, Args&& ...args)
  107. {
  108. for(auto &ptr : container)
  109. {
  110. if(ptr)
  111. {
  112. callback(*ptr, args...);
  113. }
  114. }
  115. }
  116.  
  117. //Wrappers for std::weak_ptr, with callback-function calls.
  118. template<typename Container, typename CallbackFunc, typename ...Args>
  119. void priv_ForEachPtr_impl_forWeakPtrsCallbackFunc(Container &container, CallbackFunc callback, Args&& ...args)
  120. {
  121. for(auto &weak_ptr : container)
  122. {
  123. auto shared_ptr = weak_ptr.lock();
  124.  
  125. if(shared_ptr)
  126. {
  127. callback(*shared_ptr, args...);
  128. }
  129. }
  130. }
  131.  
  132. //============================================================================
  133.  
  134. //Wrappers for std::unique_ptr and std::shared_ptr, with member-function calls.
  135. template<typename Container, typename MemberFunc, typename ...Args>
  136. void priv_ForEachPtr_impl_forSharedOrUniquePtrsMemberFunc(Container &container, MemberFunc member_func, Args&& ...args)
  137. {
  138. for(auto &ptr : container)
  139. {
  140. if(ptr)
  141. {
  142. ((*ptr).*member_func)(args...);
  143. }
  144. }
  145. }
  146.  
  147. //Wrappers for std::weak_ptr, with member-function calls.
  148. template<typename Container, typename MemberFunc, typename ...Args>
  149. void priv_ForEachPtr_impl_forWeakPtrsMemberFunc(Container &container, MemberFunc member_func, Args&& ...args)
  150. {
  151. for(auto &weak_ptr : container)
  152. {
  153. auto shared_ptr = weak_ptr.lock();
  154.  
  155. if(shared_ptr)
  156. {
  157. ((*shared_ptr).*member_func)(args...);
  158. }
  159. }
  160. }
  161.  
  162. //============================================================================
  163.  
  164. //Overload for vectors of unique_ptr.
  165. template<typename ElementType, typename ...MembFuncArgs, typename ...ParamArgs>
  166. void ForEachPtr(std::vector<std::unique_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
  167. {
  168. priv_ForEachPtr_impl_forSharedOrUniquePtrsMemberFunc(container, member_func, std::forward<ParamArgs>(args)...);
  169. }
  170. template<typename ElementType, typename ...MembFuncArgs, typename ...ParamArgs>
  171. void ForEachPtr(const std::vector<std::unique_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...) const, ParamArgs&& ...args)
  172. {
  173. priv_ForEachPtr_impl_forSharedOrUniquePtrsMemberFunc(container, member_func, std::forward<ParamArgs>(args)...);
  174. }
  175.  
  176. //============================================================================
  177.  
  178. //Overload for vectors of shared_ptr.
  179. template<typename ElementType, typename ...MembFuncArgs, typename ...ParamArgs>
  180. void ForEachPtr(std::vector<std::shared_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
  181. {
  182. priv_ForEachPtr_impl_forSharedOrUniquePtrsMemberFunc(container, member_func, std::forward<ParamArgs>(args)...);
  183. }
  184. template<typename ElementType, typename ...MembFuncArgs, typename ...ParamArgs>
  185. void ForEachPtr(const std::vector<std::shared_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...) const, ParamArgs&& ...args)
  186. {
  187. priv_ForEachPtr_impl_forSharedOrUniquePtrsMemberFunc(container, member_func, std::forward<ParamArgs>(args)...);
  188. }
  189.  
  190. //============================================================================
  191.  
  192. //Overload for vectors of weak_ptr.
  193. template<typename ElementType, typename ...MembFuncArgs, typename ...ParamArgs>
  194. void ForEachPtr(std::vector<std::weak_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
  195. {
  196. priv_ForEachPtr_impl_forSharedOrUniquePtrsMemberFunc(container, member_func, std::forward<ParamArgs>(args)...);
  197. }
  198. template<typename ElementType, typename ...MembFuncArgs, typename ...ParamArgs>
  199. void ForEachPtr(const std::vector<std::weak_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...) const, ParamArgs&& ...args)
  200. {
  201. priv_ForEachPtr_impl_forSharedOrUniquePtrsMemberFunc(container, member_func, std::forward<ParamArgs>(args)...);
  202. }
  203.  
  204. //============================================================================
  205.  
  206. #endif // COMMON_ALGORITHM_FOREACH_H
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:166:22: error: variable or field 'ForEachPtr' declared void
 void ForEachPtr(std::vector<std::unique_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
                      ^
prog.cpp:166:17: error: 'vector' is not a member of 'std'
 void ForEachPtr(std::vector<std::unique_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
                 ^
prog.cpp:166:56: error: expected primary-expression before '>' token
 void ForEachPtr(std::vector<std::unique_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
                                                        ^
prog.cpp:166:60: error: 'container' was not declared in this scope
 void ForEachPtr(std::vector<std::unique_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
                                                            ^
prog.cpp:166:71: error: expected primary-expression before 'void'
 void ForEachPtr(std::vector<std::unique_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
                                                                       ^
prog.cpp:166:131: error: expected primary-expression before '&&' token
 void ForEachPtr(std::vector<std::unique_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
                                                                                                                                   ^
prog.cpp:166:134: error: expected primary-expression before '...' token
 void ForEachPtr(std::vector<std::unique_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
                                                                                                                                      ^
prog.cpp:171:28: error: 'vector' in namespace 'std' does not name a template type
 void ForEachPtr(const std::vector<std::unique_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...) const, ParamArgs&& ...args)
                            ^
prog.cpp:171:34: error: expected ',' or '...' before '<' token
 void ForEachPtr(const std::vector<std::unique_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...) const, ParamArgs&& ...args)
                                  ^
prog.cpp: In function 'void ForEachPtr(int)':
prog.cpp:173:55: error: 'container' was not declared in this scope
  priv_ForEachPtr_impl_forSharedOrUniquePtrsMemberFunc(container, member_func, std::forward<ParamArgs>(args)...);
                                                       ^
prog.cpp:173:66: error: 'member_func' was not declared in this scope
  priv_ForEachPtr_impl_forSharedOrUniquePtrsMemberFunc(container, member_func, std::forward<ParamArgs>(args)...);
                                                                  ^
prog.cpp:173:103: error: 'args' was not declared in this scope
  priv_ForEachPtr_impl_forSharedOrUniquePtrsMemberFunc(container, member_func, std::forward<ParamArgs>(args)...);
                                                                                                       ^
prog.cpp: At global scope:
prog.cpp:180:22: error: variable or field 'ForEachPtr' declared void
 void ForEachPtr(std::vector<std::shared_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
                      ^
prog.cpp:180:17: error: 'vector' is not a member of 'std'
 void ForEachPtr(std::vector<std::shared_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
                 ^
prog.cpp:180:56: error: expected primary-expression before '>' token
 void ForEachPtr(std::vector<std::shared_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
                                                        ^
prog.cpp:180:60: error: 'container' was not declared in this scope
 void ForEachPtr(std::vector<std::shared_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
                                                            ^
prog.cpp:180:71: error: expected primary-expression before 'void'
 void ForEachPtr(std::vector<std::shared_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
                                                                       ^
prog.cpp:180:131: error: expected primary-expression before '&&' token
 void ForEachPtr(std::vector<std::shared_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
                                                                                                                                   ^
prog.cpp:180:134: error: expected primary-expression before '...' token
 void ForEachPtr(std::vector<std::shared_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
                                                                                                                                      ^
prog.cpp:185:28: error: 'vector' in namespace 'std' does not name a template type
 void ForEachPtr(const std::vector<std::shared_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...) const, ParamArgs&& ...args)
                            ^
prog.cpp:185:34: error: expected ',' or '...' before '<' token
 void ForEachPtr(const std::vector<std::shared_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...) const, ParamArgs&& ...args)
                                  ^
prog.cpp:185:6: error: redefinition of 'template<class ElementType, class ... MembFuncArgs, class ... ParamArgs> void ForEachPtr(int)'
 void ForEachPtr(const std::vector<std::shared_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...) const, ParamArgs&& ...args)
      ^
prog.cpp:171:6: note: 'template<class ElementType, class ... MembFuncArgs, class ... ParamArgs> void ForEachPtr(int)' previously declared here
 void ForEachPtr(const std::vector<std::unique_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...) const, ParamArgs&& ...args)
      ^
prog.cpp:194:22: error: variable or field 'ForEachPtr' declared void
 void ForEachPtr(std::vector<std::weak_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
                      ^
prog.cpp:194:17: error: 'vector' is not a member of 'std'
 void ForEachPtr(std::vector<std::weak_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
                 ^
prog.cpp:194:54: error: expected primary-expression before '>' token
 void ForEachPtr(std::vector<std::weak_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
                                                      ^
prog.cpp:194:58: error: 'container' was not declared in this scope
 void ForEachPtr(std::vector<std::weak_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
                                                          ^
prog.cpp:194:69: error: expected primary-expression before 'void'
 void ForEachPtr(std::vector<std::weak_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
                                                                     ^
prog.cpp:194:129: error: expected primary-expression before '&&' token
 void ForEachPtr(std::vector<std::weak_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
                                                                                                                                 ^
prog.cpp:194:132: error: expected primary-expression before '...' token
 void ForEachPtr(std::vector<std::weak_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...), ParamArgs&& ...args)
                                                                                                                                    ^
prog.cpp:199:28: error: 'vector' in namespace 'std' does not name a template type
 void ForEachPtr(const std::vector<std::weak_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...) const, ParamArgs&& ...args)
                            ^
prog.cpp:199:34: error: expected ',' or '...' before '<' token
 void ForEachPtr(const std::vector<std::weak_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...) const, ParamArgs&& ...args)
                                  ^
prog.cpp:199:6: error: redefinition of 'template<class ElementType, class ... MembFuncArgs, class ... ParamArgs> void ForEachPtr(int)'
 void ForEachPtr(const std::vector<std::weak_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...) const, ParamArgs&& ...args)
      ^
prog.cpp:171:6: note: 'template<class ElementType, class ... MembFuncArgs, class ... ParamArgs> void ForEachPtr(int)' previously declared here
 void ForEachPtr(const std::vector<std::unique_ptr<ElementType>> &container, void (ElementType::*member_func)(MembFuncArgs...) const, ParamArgs&& ...args)
      ^
stdout
Standard output is empty