// 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 "carla/MsgPack.h" #include "carla/MsgPackAdaptors.h" #include #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable:4583) #pragma warning(disable:4582) #include #pragma warning(pop) #else #include #endif #include namespace carla { namespace rpc { class ResponseError { public: ResponseError() = default; explicit ResponseError(std::string message) : _what(std::move(message)) {} const std::string &What() const { return _what; } MSGPACK_DEFINE_ARRAY(_what) private: /// @todo Needs initialization, empty strings end up calling memcpy on a /// nullptr. Possibly a bug in MsgPack but could also be our specialization /// for variants std::string _what{"unknown error"}; }; template class Response { public: using value_type = T; using error_type = ResponseError; Response() = default; template Response(TValue &&value) : _data(std::forward(value)) {} template void Reset(TValue &&value) { _data = std::forward(value); } bool HasError() const { return _data.index() == 0; } template void SetError(Ts &&... args) { _data = error_type(std::forward(args)...); } const error_type &GetError() const { DEBUG_ASSERT(HasError()); return boost::variant2::get(_data); } value_type &Get() { DEBUG_ASSERT(!HasError()); return boost::variant2::get(_data); } const value_type &Get() const { DEBUG_ASSERT(!HasError()); return boost::variant2::get(_data); } operator bool() const { return !HasError(); } MSGPACK_DEFINE_ARRAY(_data) private: boost::variant2::variant _data; }; template <> class Response { public: using value_type = void; using error_type = ResponseError; static Response Success() { return success_flag{}; } Response() : _data(error_type{}) {} Response(ResponseError error) : _data(std::move(error)) {} bool HasError() const { return _data.has_value(); } template void SetError(Ts &&... args) { _data = error_type(std::forward(args)...); } const error_type &GetError() const { DEBUG_ASSERT(HasError()); return *_data; } operator bool() const { return !HasError(); } MSGPACK_DEFINE_ARRAY(_data) private: struct success_flag {}; Response(success_flag) {} boost::optional _data; }; } // namespace rpc } // namespace carla