@@ -50,12 +50,71 @@ class GenericCallableImpl : public GenericCallable<RetT, ArgTs...> {
5050 CallableT Callable;
5151};
5252
53+ template <typename RetT, typename ... ArgTs> class GenericConstCallable {
54+ public:
55+ virtual ~GenericConstCallable () = default ;
56+ virtual RetT call (ArgTs &&...Args) const = 0;
57+ };
58+
59+ template <typename CallableT, typename RetT, typename ... ArgTs>
60+ class GenericConstCallableImpl : public GenericConstCallable <RetT, ArgTs...> {
61+ public:
62+ GenericConstCallableImpl (CallableT &&Callable)
63+ : Callable(std::move(Callable)) {}
64+ RetT call (ArgTs &&...Args) const override {
65+ return Callable (std::forward<ArgTs>(Args)...);
66+ }
67+
68+ private:
69+ CallableT Callable;
70+ };
71+
5372} // namespace move_only_function_detail
5473
5574template <typename FnT> class move_only_function ;
5675
5776template <typename RetT, typename ... ArgTs>
5877class move_only_function <RetT(ArgTs...)> {
78+ private:
79+ using GenericCallable =
80+ move_only_function_detail::GenericCallable<RetT, ArgTs...>;
81+ template <typename CallableT>
82+ using GenericCallableImpl =
83+ move_only_function_detail::GenericCallableImpl<CallableT, RetT, ArgTs...>;
84+
85+ public:
86+ move_only_function () = default ;
87+ move_only_function (std::nullptr_t ) {}
88+ move_only_function (move_only_function &&) = default ;
89+ move_only_function (const move_only_function &) = delete ;
90+ move_only_function &operator =(move_only_function &&) = default ;
91+ move_only_function &operator =(const move_only_function &) = delete ;
92+
93+ template <typename CallableT>
94+ move_only_function (CallableT &&Callable)
95+ : C(std::make_unique<GenericCallableImpl<std::decay_t <CallableT>>>(
96+ std::move (Callable))) {}
97+
98+ RetT operator ()(ArgTs... Params) const {
99+ return C->call (std::forward<ArgTs>(Params)...);
100+ }
101+
102+ explicit operator bool () const { return !!C; }
103+
104+ private:
105+ std::unique_ptr<GenericCallable> C;
106+ };
107+
108+ template <typename RetT, typename ... ArgTs>
109+ class move_only_function <RetT(ArgTs...) const > {
110+ private:
111+ using GenericCallable =
112+ move_only_function_detail::GenericConstCallable<RetT, ArgTs...>;
113+ template <typename CallableT>
114+ using GenericCallableImpl =
115+ move_only_function_detail::GenericConstCallableImpl<CallableT, RetT,
116+ ArgTs...>;
117+
59118public:
60119 move_only_function () = default ;
61120 move_only_function (std::nullptr_t ) {}
@@ -66,17 +125,17 @@ class move_only_function<RetT(ArgTs...)> {
66125
67126 template <typename CallableT>
68127 move_only_function (CallableT &&Callable)
69- : C(std::make_unique<move_only_function_detail::GenericCallableImpl<
70- std:: decay_t <CallableT>, RetT, ArgTs...>>( std::move(Callable))) {}
128+ : C(std::make_unique<const GenericCallableImpl<std:: decay_t <CallableT>>>(
129+ std::move (Callable))) {}
71130
72- RetT operator ()(ArgTs... Params) {
131+ RetT operator ()(ArgTs... Params) const {
73132 return C->call (std::forward<ArgTs>(Params)...);
74133 }
75134
76135 explicit operator bool () const { return !!C; }
77136
78137private:
79- std::unique_ptr<move_only_function_detail::GenericCallable<RetT, ArgTs...> > C;
138+ std::unique_ptr<const GenericCallable > C;
80139};
81140
82141} // namespace orc_rt
0 commit comments