cpp-toolbox  0.0.1
A toolbox library for C++
Loading...
Searching...
No Matches
functional.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm>
4#include <functional> // 可能有用,但compose本身不需要 / Potentially useful, though not strictly required by compose itself
5#include <iostream>
6#include <iterator>
7#include <map>
8#include <memory> // std::shared_ptr, std::make_shared
9#include <mutex> // std::mutex
10#include <numeric>
11#include <optional>
12#include <stdexcept>
13#include <string>
14#include <type_traits> // std::invoke_result_t, std::decay_t
15#include <typeinfo>
16#include <utility> // std::forward, std::move
17#include <variant>
18
19#include <cpp-toolbox/cpp-toolbox_export.hpp>
20
55#define CPP_TOOLBOX_DEFINE_SIMPLE_FUNCTOR( \
56 FunctorName, ReturnType, Params, Body) \
57 struct FunctorName \
58 { \
59 ReturnType operator() Params const \
60 { \
61 Body \
62 } \
63 };
64
66{
67
68namespace detail
69{
82template<class... Fs>
83struct overloaded : Fs...
84{
85 using Fs::operator()...; // C++17 using包声明 / C++17 using pack declaration
86};
87
88// C++17类模板参数推导指南 / C++17 class template argument deduction guide
89// 允许写overloaded{lambda1, lambda2}而不需要显式模板参数 / Allows writing
90// overloaded{lambda1, lambda2} without explicit template args
91template<class... Fs>
92overloaded(Fs...) -> overloaded<Fs...>;
93
104template<typename T>
105struct is_optional : std::false_type
106{
107};
108
109template<typename T>
110struct is_optional<std::optional<T>> : std::true_type
111{
112};
113
114template<typename T>
115inline constexpr bool is_optional_v = is_optional<std::decay_t<T>>::value;
116
126template<typename T, typename = void>
127struct has_size : std::false_type
128{
129};
130
131template<typename T>
132struct has_size<T, std::void_t<decltype(std::declval<T>().size())>>
133 : std::true_type
134{
135};
136
150template<typename... Containers>
151auto get_min_size(const Containers&... containers) -> size_t
152{
153 if constexpr (sizeof...(containers) == 0) {
154 return 0; // 显式处理空包 / Handle empty pack explicitly
155 } else {
156 return std::min({static_cast<size_t>(containers.size())...});
157 }
158}
159
170template<typename Tuple, std::size_t... Is>
171void increment_iterators(Tuple& iter_tuple, std::index_sequence<Is...>)
172{
173 (++(std::get<Is>(iter_tuple)), ...);
174}
175
186template<typename Tuple, std::size_t... Is>
187auto dereference_iterators_as_tuple(Tuple& iter_tuple,
188 std::index_sequence<Is...>)
189{
190 return std::forward_as_tuple(*(std::get<Is>(iter_tuple))...);
191}
192
201template<typename Func, typename R, typename... Args>
203{
204 using KeyType = std::tuple<std::decay_t<Args>...>;
205 using ResultType = R;
206
208 std::map<KeyType, ResultType> cache;
209 std::mutex cache_mutex;
210
211 MemoizeState(Func&& f)
212 : original_func(std::forward<Func>(f))
213 {
214 }
215};
216} // namespace detail
217
236template<typename G, typename F>
237CPP_TOOLBOX_EXPORT auto compose(G&& g, F&& f);
238
259template<typename F1, typename... FRest>
260CPP_TOOLBOX_EXPORT auto compose(F1&& f1, FRest&&... rest);
261
275inline CPP_TOOLBOX_EXPORT auto compose();
276
292template<typename F, typename Arg1>
293CPP_TOOLBOX_EXPORT auto bind_first(F&& f, Arg1&& arg1);
294
311template<typename T, typename F>
312CPP_TOOLBOX_EXPORT auto map(const std::optional<T>& opt, F&& f)
313 -> std::optional<std::invoke_result_t<F, const T&>>;
314
330template<typename T, typename F>
331CPP_TOOLBOX_EXPORT auto map(std::optional<T>&& opt, F&& f)
332 -> std::optional<std::invoke_result_t<F, T&&>>;
333
353template<typename T, typename F>
354CPP_TOOLBOX_EXPORT auto flatMap(const std::optional<T>& opt, F&& f)
355 -> std::invoke_result_t<F, const T&>;
356
375template<typename T, typename F>
376CPP_TOOLBOX_EXPORT auto flatMap(std::optional<T>&& opt, F&& f)
377 -> std::invoke_result_t<F, T&&>;
378
394template<typename T, typename U>
395CPP_TOOLBOX_EXPORT auto orElse(const std::optional<T>& opt, U&& default_value)
396 -> T;
397
415template<typename T, typename F>
416CPP_TOOLBOX_EXPORT auto orElseGet(const std::optional<T>& opt, F&& default_func)
417 -> T;
418
435template<typename T, typename P>
436CPP_TOOLBOX_EXPORT auto filter(const std::optional<T>& opt, P&& p)
437 -> std::optional<T>;
438
455template<typename T, typename P>
456CPP_TOOLBOX_EXPORT auto filter(std::optional<T>&& opt, P&& p)
457 -> std::optional<T>;
458
477template<typename... Ts, typename... Fs>
478CPP_TOOLBOX_EXPORT auto match(const std::variant<Ts...>& var, Fs&&... visitors)
479 -> decltype(auto);
480
498template<typename... Ts, typename... Fs>
499CPP_TOOLBOX_EXPORT auto match(std::variant<Ts...>& var, Fs&&... visitors)
500 -> decltype(auto);
501
519template<typename... Ts, typename... Fs>
520CPP_TOOLBOX_EXPORT auto match(std::variant<Ts...>&& var, Fs&&... visitors)
521 -> decltype(auto);
522
553template<typename ResultVariant, typename... Ts, typename F>
554CPP_TOOLBOX_EXPORT auto map(const std::variant<Ts...>& var, F&& f)
555 -> ResultVariant;
556
577template<typename ResultVariant, typename... Ts, typename F>
578CPP_TOOLBOX_EXPORT auto map(std::variant<Ts...>& var, F&& f) -> ResultVariant;
579
599template<typename ResultVariant, typename... Ts, typename F>
600CPP_TOOLBOX_EXPORT auto map(std::variant<Ts...>&& var, F&& f) -> ResultVariant;
601
625template<typename Container, typename Func>
626CPP_TOOLBOX_EXPORT auto map(const Container& input, Func&& f) -> std::vector<
627 std::invoke_result_t<Func, typename Container::const_reference>>;
628
652template<typename Container, typename Predicate>
653CPP_TOOLBOX_EXPORT auto filter(const Container& input, Predicate&& p)
654 -> std::vector<typename Container::value_type>;
655
684template<typename Container, typename T, typename BinaryOp>
685CPP_TOOLBOX_EXPORT auto reduce(const Container& input,
686 T identity,
687 BinaryOp&& op) -> T;
688
717template<typename Container, typename BinaryOp>
718CPP_TOOLBOX_EXPORT auto reduce(const Container& input, BinaryOp&& op) ->
719 typename Container::value_type;
720
748template<typename... Containers>
749CPP_TOOLBOX_EXPORT auto zip(const Containers&... containers) -> std::vector<
750 std::tuple<decltype(*std::cbegin(std::declval<const Containers&>()))...>>;
751
786template<typename ContainerKeys,
787 typename ContainerValues,
788 typename Key = typename std::decay_t<ContainerKeys>::value_type,
789 typename Value = typename std::decay_t<ContainerValues>::value_type,
790 typename Hash = std::hash<Key>,
791 typename KeyEqual = std::equal_to<Key>,
792 typename Alloc = std::allocator<std::pair<const Key, Value>>>
793CPP_TOOLBOX_EXPORT auto zip_to_unordered_map(const ContainerKeys& keys,
794 const ContainerValues& values)
795 -> std::unordered_map<Key, Value, Hash, KeyEqual, Alloc>;
796
819template<typename Signature>
820class CPP_TOOLBOX_EXPORT MemoizedFunction; // 前向声明 / Forward declaration
821
827template<typename R, typename... Args>
828class CPP_TOOLBOX_EXPORT MemoizedFunction<R(Args...)>
829{
830private:
831 using FuncType = std::function<R(Args...)>;
832 using KeyType = std::tuple<std::decay_t<Args>...>;
833 using ResultType = R;
834
835 // 使用pimpl惯用法或shared_ptr隐藏实现细节 / Use pimpl idiom or shared_ptr to
836 // hide implementation details 这避免在头文件中包含<map>和<mutex> / This
837 // avoids including <map> and <mutex> in the header
838 struct State; // 前向声明状态结构 / Forward declare the state struct
839 std::shared_ptr<State>
840 state_; // 指向实现状态的指针 / Pointer to implementation state
841
842public:
843 explicit MemoizedFunction(FuncType f);
844
845 MemoizedFunction(const MemoizedFunction&) = delete;
846 MemoizedFunction& operator=(const MemoizedFunction&) = delete;
847 // 允许移动 / Allow moving
848 MemoizedFunction(MemoizedFunction&&) noexcept = default;
849 MemoizedFunction& operator=(MemoizedFunction&&) noexcept = default;
850
851 auto operator()(Args... args) -> ResultType;
852};
853
871template<typename Signature, typename Func>
872CPP_TOOLBOX_EXPORT auto memoize(Func&& f);
873
898template<typename R, typename... Args, typename Func>
899CPP_TOOLBOX_EXPORT auto memoize_explicit(Func&& f) -> std::function<R(Args...)>;
900
901} // namespace toolbox::functional
902
903#include <cpp-toolbox/functional/impl/functional_impl.hpp>
MemoizedFunction & operator=(const MemoizedFunction &)=delete
MemoizedFunction(const MemoizedFunction &)=delete
MemoizedFunction(MemoizedFunction &&) noexcept=default
auto dereference_iterators_as_tuple(Tuple &iter_tuple, std::index_sequence< Is... >)
解引用迭代器并创建引用元组的辅助函数 / Helper function to dereference iterators and create tuple of references
Definition functional.hpp:187
auto get_min_size(const Containers &... containers) -> size_t
获取多个容器中的最小大小的辅助函数 / Helper function to get minimum size from multiple containers
Definition functional.hpp:151
constexpr bool is_optional_v
Definition functional.hpp:115
void increment_iterators(Tuple &iter_tuple, std::index_sequence< Is... >)
增加元组中所有迭代器的辅助函数 / Helper function to increment all iterators in a tuple
Definition functional.hpp:171
Definition functional.hpp:66
CPP_TOOLBOX_EXPORT auto reduce(const Container &input, T identity, BinaryOp &&op) -> T
使用带初始值的二元操作归约容器元素 / Reduce container elements using a binary operation with initial value
Definition functional_impl.hpp:424
CPP_TOOLBOX_EXPORT auto orElseGet(const std::optional< T > &opt, F &&default_func) -> T
返回包含的值或调用函数获取默认值 / Returns the contained value or calls function for default
Definition functional_impl.hpp:224
CPP_TOOLBOX_EXPORT auto filter(const std::optional< T > &opt, P &&p) -> std::optional< T >
基于谓词过滤optional / Filters an optional based on a predicate
Definition functional_impl.hpp:242
CPP_TOOLBOX_EXPORT auto zip_to_unordered_map(const ContainerKeys &keys, const ContainerValues &values) -> std::unordered_map< Key, Value, Hash, KeyEqual, Alloc >
将两个序列压缩成无序映射 / Zip two sequences into an unordered_map
Definition functional_impl.hpp:490
CPP_TOOLBOX_EXPORT auto orElse(const std::optional< T > &opt, U &&default_value) -> T
返回包含的值或默认值 / Returns the contained value or a default
Definition functional_impl.hpp:214
CPP_TOOLBOX_EXPORT auto match(const std::variant< Ts... > &var, Fs &&... visitors) -> decltype(auto)
使用访问器函数对variant进行模式匹配 / Pattern matches on a variant using visitor functions
Definition functional_impl.hpp:286
CPP_TOOLBOX_EXPORT auto compose()
空的compose函数,会抛出错误 / Empty compose function that throws an error
Definition functional_impl.hpp:136
CPP_TOOLBOX_EXPORT auto map(const std::optional< T > &opt, F &&f) -> std::optional< std::invoke_result_t< F, const T & > >
在optional值上映射函数 / Maps a function over an optional value
Definition functional_impl.hpp:153
CPP_TOOLBOX_EXPORT auto flatMap(const std::optional< T > &opt, F &&f) -> std::invoke_result_t< F, const T & >
在optional值上平面映射函数 / Flat maps a function over an optional value
Definition functional_impl.hpp:182
CPP_TOOLBOX_EXPORT auto zip(const Containers &... containers) -> std::vector< std::tuple< decltype(*std::cbegin(std::declval< const Containers & >()))... > >
将多个容器压缩成元组向量 / Zip multiple containers into a vector of tuples
Definition functional_impl.hpp:452
class CPP_TOOLBOX_EXPORT MemoizedFunction
缓存函数结果的记忆化函数类 / Memoized function class that caches function results
Definition functional.hpp:820
CPP_TOOLBOX_EXPORT auto bind_first(F &&f, Arg1 &&arg1)
绑定函数的第一个参数 / Binds the first argument of a function
Definition functional_impl.hpp:142
记忆化的内部状态 / Internal state for memoization
Definition functional.hpp:203
R ResultType
Definition functional.hpp:205
Func original_func
Definition functional.hpp:207
std::mutex cache_mutex
Definition functional.hpp:209
MemoizeState(Func &&f)
Definition functional.hpp:211
std::tuple< std::decay_t< Args >... > KeyType
Definition functional.hpp:204
std::map< KeyType, ResultType > cache
Definition functional.hpp:208
检查类型是否有size()成员函数的类型特征 / Type trait to check if type has size() member function
Definition functional.hpp:128
检查T是否为std::optional的类型特征 / Type trait to check if T is a std::optional
Definition functional.hpp:106
用于创建重载集的辅助类 / Helper class for creating overload sets
Definition functional.hpp:84