// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma // de Barcelona (UAB). // // This work is licensed under the terms of the MIT license. // For a copy, see . #pragma once #include namespace carla { class Functional { public: /// Creates a recursive callable object, where the itself is passed as first /// argument to @a func. Use case: create recursive lambda. template static auto MakeRecursive(FuncT &&func) { return Recursive(std::forward(func)); } /// Creates an "overloaded callable object" out of one or more callable /// objects, each callable object will contribute with an overload of /// operator(). Use case: combine several lambdas into a single lambda. template static auto MakeOverload(FuncTs &&... fs) { return Overload(std::forward(fs)...); } /// @see MakeRecursive and MakeOverload. template static auto MakeRecursiveOverload(FuncTs &&... fs) { return MakeRecursive(MakeOverload(std::forward(fs)...)); } private: template struct Overload; template struct Overload : T, Overload { Overload(T &&func, Ts &&... rest) : T(std::forward(func)), Overload(std::forward(rest)...) {} using T::operator(); using Overload::operator(); }; template struct Overload : T { Overload(T &&func) : T(std::forward(func)) {} using T::operator(); }; template struct Recursive { explicit Recursive(T &&func) : _func(std::forward(func)) {} template auto operator()(Ts &&... arguments) const { return _func(*this, std::forward(arguments)...); } private: T _func; }; }; } // namespace carla