File indexing completed on 2024-06-16 05:06:54

0001 /*
0002     SPDX-FileCopyrightText: 2018 Ivan Čukić <ivan.cukic(at)kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #ifndef VOY_OPERATIONS_TRANSFORM_H
0008 #define VOY_OPERATIONS_TRANSFORM_H
0009 
0010 // STL
0011 #include <functional>
0012 
0013 // Self
0014 #include "../utils.h"
0015 #include "../traits.h"
0016 #include "../dsl/node_tags.h"
0017 
0018 namespace voy {
0019 
0020 using voy::utils::non_copyable;
0021 
0022 using voy::dsl::continuator_base,
0023       voy::dsl::transformation_node_tag;
0024 
0025 template <typename Traf>
0026 class transform {
0027 public:
0028     using node_category = transformation_node_tag;
0029 
0030     explicit transform(Traf transformation)
0031         : m_transformation(std::move(transformation))
0032     {
0033     }
0034 
0035     template <typename Cont>
0036     class node: public continuator_base<Cont>, non_copyable {
0037         using base = continuator_base<Cont>;
0038 
0039     public:
0040         node(Traf transformation, Cont&& continuation)
0041             : base{std::move(continuation)}
0042             , m_transformation{std::move(transformation)}
0043         {
0044         }
0045 
0046         template <typename T>
0047         void operator() (T&& value) const
0048         {
0049             base::emit(voy_fwd_invoke(m_transformation, value));
0050         }
0051 
0052     private:
0053         Traf m_transformation;
0054     };
0055 
0056     template <typename Cont>
0057     auto with_continuation(Cont&& cont) &&
0058     {
0059         return node<Cont>(std::move(m_transformation), voy_fwd(cont));
0060     }
0061 
0062     template < typename Cont
0063              , voy_require(std::is_copy_constructible_v<Traf>)
0064              >
0065     auto with_continuation(Cont&& cont) const
0066     {
0067         return node(m_transformation, voy_fwd(cont));
0068     }
0069 
0070 private:
0071     Traf m_transformation;
0072 };
0073 
0074 template <typename Type>
0075 inline auto cast_to = transform {
0076         [] (auto&& value) {
0077             return static_cast<Type>(voy_fwd(value));
0078         }
0079     };
0080 
0081 } // namespace voy
0082 
0083 #endif // include guard
0084