Loading...
Searching...
No Matches
enumerate.h
Go to the documentation of this file.
1#ifndef _BBM_ENUMERATE_H_
2#define _BBM_ENUMERATE_H_
3
4#include <concepts>
5#include "concepts/util.h"
6
7/***********************************************************************/
8/*! \file enumerate.h
9 \brief Enumerate all elements in iterators recursively.
10
11 Enumerate all elements of in an iterable type recursively
12 until the element can be cast to a given VALUE type. The value is than
13 passed into a provided callback function:
14
15 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c}
16 enumerate<float>(data, [&](auto& val) { some_vector.push_back(val); });
17 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
18
19 will enumerate all elements in data, and push them onto 'some_vector'.
20
21************************************************************************/
22
23namespace bbm {
24
25 /*********************************************************************/
26 /*! \brief Convertible to VALUE => callback
27 *********************************************************************/
28 template<typename VALUE, typename T, typename CALLBACK> requires (std::convertible_to<T&, VALUE> && std::invocable<CALLBACK, VALUE>)
29 void enumerate(T&& value, CALLBACK&& callback)
30 {
31 callback(std::forward<decltype(value)>(value));
32 }
33
34 /*********************************************************************/
35 /*! \brief iterable object => enumerate(begin(), ..., end())
36 *********************************************************************/
37 template<typename VALUE, typename T, typename CALLBACK> requires (std::ranges::range<T> && !std::convertible_to<T&, VALUE> && std::invocable<CALLBACK, VALUE>)
38 void enumerate(T&& obj, CALLBACK&& callback)
39 {
40 for(auto&& val : obj)
41 enumerate<VALUE>(std::forward<decltype(val)>(val), std::forward<CALLBACK>(callback));
42 }
43
44
45 /*** Implementation details for is_enumerable ***/
46 namespace detail {
47
48 // default case
49 template<typename VALUE, typename T> struct is_enumerable_impl : std::false_type {};
50
51 // base case
52 template<typename VALUE, typename T> requires std::is_convertible_v<T&, VALUE>
53 struct is_enumerable_impl<VALUE, T> : std::true_type {};
54
55 // iterable
56 template<typename VALUE, typename T> requires (std::ranges::range<T> && !std::is_convertible_v<T&, VALUE>)
57 struct is_enumerable_impl<VALUE, T> : is_enumerable_impl<VALUE, decltype( *std::begin(std::declval<T>()) ) > {};
58
59 } // end detail namespace
60
61 /*********************************************************************/
62 /*! @{ \name is_enumerable
63 *********************************************************************/
64 template<typename VALUE, typename T>
65 using is_enumerable = bbm::detail::is_enumerable_impl<VALUE, T>;
66
67 template<typename VALUE, typename T>
69 //! @}
70
71} // end bbm namespace
72
73
74#endif /* _BBM_ENUMERATE_H_ */
Definition: aggregatebsdf.h:29
constexpr bool is_enumerable_v
Definition: enumerate.h:68
bbm::detail::is_enumerable_impl< VALUE, T > is_enumerable
Definition: enumerate.h:65
void enumerate(T &&value, CALLBACK &&callback)
Convertible to VALUE => callback.
Definition: enumerate.h:29
decltype(auto) value(T &&t)
return the value of an attribute, or if not an attribute the object
Definition: attribute_value.h:20
Additional basic helper concepts.