Refactor overload methods into Functional class

This commit is contained in:
nsubiron 2019-04-17 13:09:41 +02:00
parent bdc12cbe64
commit 73f0bc8647
3 changed files with 80 additions and 68 deletions

View File

@ -0,0 +1,77 @@
// 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 <https://opensource.org/licenses/MIT>.
#pragma once
#include <utility>
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 <typename FuncT>
static auto MakeRecursive(FuncT &&func) {
return Recursive<FuncT>(std::forward<FuncT>(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 <typename... FuncTs>
static auto MakeOverload(FuncTs &&... fs) {
return Overload<FuncTs...>(std::forward<FuncTs>(fs)...);
}
/// @see MakeRecursive and MakeOverload.
template <typename... FuncTs>
static auto MakeRecursiveOverload(FuncTs &&... fs) {
return MakeRecursive(MakeOverload(std::forward<FuncTs>(fs)...));
}
private:
template <typename... Ts>
struct Overload;
template <typename T, typename... Ts>
struct Overload<T, Ts...> : T, Overload<Ts...> {
Overload(T &&func, Ts &&... rest)
: T(std::forward<T>(func)),
Overload<Ts...>(std::forward<Ts>(rest)...) {}
using T::operator();
using Overload<Ts...>::operator();
};
template <typename T>
struct Overload<T> : T {
Overload(T &&func) : T(std::forward<T>(func)) {}
using T::operator();
};
template<typename T>
struct Recursive {
explicit Recursive(T &&func) : _func(std::forward<T>(func)) {}
template<typename... Ts>
auto operator()(Ts &&... arguments) const {
return _func(*this, std::forward<Ts>(arguments)...);
}
private:
T _func;
};
};
} // namespace carla

View File

@ -1,65 +0,0 @@
// 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 <https://opensource.org/licenses/MIT>.
#pragma once
namespace carla {
namespace detail {
template <typename... Ts>
struct Overload;
template <typename T, typename... Ts>
struct Overload<T, Ts...> : T, Overload<Ts...> {
Overload(T &&func, Ts &&... rest)
: T(std::forward<T>(func)),
Overload<Ts...>(std::forward<Ts>(rest)...) {}
using T::operator();
using Overload<Ts...>::operator();
};
template <typename T>
struct Overload<T> : T {
Overload(T &&func) : T(std::forward<T>(func)) {}
using T::operator();
};
template<typename T>
struct Recursive {
explicit Recursive(T &&func) : _func(std::move(func)) {}
template<typename... Ts>
auto operator()(Ts &&... arguments) const {
return _func(*this, std::forward<Ts>(arguments)...);
}
private:
T _func;
};
} // namespace detail
template <typename FuncT>
inline static auto MakeRecursive(FuncT &&func) {
return detail::Recursive<FuncT>(std::forward<FuncT>(func));
}
template <typename... FuncTs>
inline static auto MakeOverload(FuncTs &&... fs) {
return detail::Overload<FuncTs...>(std::forward<FuncTs>(fs)...);
}
template <typename... FuncTs>
inline static auto MakeRecursiveOverload(FuncTs &&... fs) {
return MakeRecursive(MakeOverload(std::forward<FuncTs>(fs)...));
}
} // namespace carla

View File

@ -13,7 +13,7 @@
#include "Carla/Walker/WalkerController.h"
#include <compiler/disable-ue4-macros.h>
#include <carla/Overload.h>
#include <carla/Functional.h>
#include <carla/Version.h>
#include <carla/rpc/Actor.h>
#include <carla/rpc/ActorDefinition.h>
@ -789,14 +789,14 @@ void FTheNewCarlaServer::FPimpl::BindActions()
#define MAKE_RESULT(operation) return parse_result(c.actor, operation);
auto command_visitor = carla::MakeRecursiveOverload(
auto command_visitor = carla::Functional::MakeRecursiveOverload(
[=](auto self, const C::SpawnActor &c) -> CR {
auto result = c.parent.has_value() ?
spawn_actor_with_parent(c.description, c.transform, *c.parent) :
spawn_actor(c.description, c.transform);
if (!result.HasError()) {
ActorId id = result.Get().id;
auto set_id = carla::MakeOverload(
auto set_id = carla::Functional::MakeOverload(
[](C::SpawnActor &) {},
[id](auto &s) { s.actor = id; });
for (auto command : c.do_after) {