.. _program_listing_file_foxglove_include_foxglove_parameter.hpp: Program Listing for File parameter.hpp ====================================== |exhale_lsh| :ref:`Return to documentation for file ` (``foxglove/include/foxglove/parameter.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #pragma once #include #include #include #include #include #include #include #include #include #include // NOLINTNEXTLINE(readability-identifier-naming) struct foxglove_parameter_value; // NOLINTNEXTLINE(readability-identifier-naming) struct foxglove_parameter; // NOLINTNEXTLINE(readability-identifier-naming) struct foxglove_parameter_array; namespace foxglove { enum class ParameterType : uint8_t { None, ByteArray, Float64, Float64Array, }; class ParameterValueView final { public: using Array = std::vector; using Dict = std::map; using Value = std::variant; [[nodiscard]] class ParameterValue clone() const; [[nodiscard]] Value value() const; template [[nodiscard]] bool is() const noexcept { try { auto value = this->value(); return std::holds_alternative(value); } catch (...) { // Unknown value tag. return false; } } template [[nodiscard]] T get() const { return std::get(this->value()); } private: friend class ParameterView; friend class ParameterValue; const foxglove_parameter_value* impl_; explicit ParameterValueView(const foxglove_parameter_value* ptr) : impl_(ptr) {} }; // Template specializations for ParameterValueView // // Documented manually as tparams because specializations are merged: // https://github.com/doxygen/doxygen/issues/9468 template<> [[nodiscard]] inline bool ParameterValueView::is() const noexcept { return this->is(); } template<> [[nodiscard]] inline ParameterValueView ParameterValueView::get() const { return *this; } template<> [[nodiscard]] inline std::string ParameterValueView::get() const { auto sv = this->get(); return std::string(sv); } class ParameterValue final { public: explicit ParameterValue(double value); explicit ParameterValue(int64_t value); explicit ParameterValue(bool value); explicit ParameterValue(std::string_view value); explicit ParameterValue(const char* value) : ParameterValue(std::string_view(value)) {} explicit ParameterValue(std::vector values); explicit ParameterValue(std::map values); ~ParameterValue() = default; ParameterValue(ParameterValue&& other) noexcept = default; ParameterValue& operator=(ParameterValue&& other) noexcept = default; ParameterValue(const ParameterValue&) = delete; ParameterValue& operator=(const ParameterValue&) = delete; [[nodiscard]] ParameterValue clone() const { return this->view().clone(); } [[nodiscard]] ParameterValueView view() const noexcept; template [[nodiscard]] bool is() const { return this->view().is(); } template [[nodiscard]] T get() const { return this->view().get(); } private: friend class ParameterValueView; friend class Parameter; struct Deleter { void operator()(foxglove_parameter_value* ptr) const noexcept; }; std::unique_ptr impl_; explicit ParameterValue(foxglove_parameter_value* ptr); [[nodiscard]] foxglove_parameter_value* release() noexcept; }; class ParameterView final { public: [[nodiscard]] class Parameter clone() const; [[nodiscard]] std::string_view name() const noexcept; [[nodiscard]] ParameterType type() const noexcept; [[nodiscard]] std::optional value() const noexcept; [[nodiscard]] bool hasValue() const noexcept { return this->value().has_value(); }; template [[nodiscard]] bool is() const noexcept { auto value = this->value(); return value.has_value() && value->is(); } template [[nodiscard]] bool isArray() const noexcept { if (!this->isArray()) { return false; } try { const auto& arr = this->get(); return std::all_of(arr.begin(), arr.end(), [](const ParameterValueView& elem) noexcept { return elem.is(); }); } catch (...) { return false; } } template [[nodiscard]] bool isDict() const noexcept { if (!this->isDict()) { return false; } try { const auto& dict = this->get(); return std::all_of( dict.begin(), dict.end(), [](const std::pair& elem) noexcept { return elem.second.is(); } ); } catch (...) { return false; } } [[nodiscard]] bool isByteArray() const noexcept; template [[nodiscard]] T get() const { auto value = this->value(); if (!value) { throw std::bad_optional_access(); } return value->template get(); } template [[nodiscard]] std::vector getArray() const { auto value = this->value(); if (!value) { throw std::bad_optional_access(); } const auto& arr = value->get(); std::vector result; result.reserve(arr.size()); for (const auto& elem : arr) { result.push_back(elem.get()); } return result; } template [[nodiscard]] std::map getDict() const { auto value = this->value(); if (!value) { throw std::bad_optional_access(); } const auto& dict = value->get(); std::map result; for (const auto& [dictKey, dictValue] : dict) { result.emplace(dictKey, dictValue.template get()); } return result; } [[nodiscard]] FoxgloveResult> getByteArray() const; private: friend class Parameter; friend class ParameterArrayView; const foxglove_parameter* impl_; explicit ParameterView(const foxglove_parameter* ptr) : impl_(ptr) {} }; template<> [[nodiscard]] inline bool ParameterView::isArray() const noexcept { auto value = this->value(); return value.has_value() && value->is(); } template<> [[nodiscard]] inline bool ParameterView::isDict() const noexcept { auto value = this->value(); return value.has_value() && value->is(); } // Template specializations for ParameterView // // Documented manually as tparams because specializations are merged: // https://github.com/doxygen/doxygen/issues/9468 template<> [[nodiscard]] inline bool ParameterView::is() const noexcept { auto value = this->value(); return value.has_value() && value->is() && this->type() != ParameterType::ByteArray; } template<> [[nodiscard]] inline bool ParameterView::is() const noexcept { return this->is(); } template<> [[nodiscard]] inline bool ParameterView::is>() const noexcept { auto value = this->value(); return value.has_value() && value->is() && this->type() == ParameterType::ByteArray; } template<> [[nodiscard]] inline bool ParameterView::is>() const noexcept { return this->isArray(); } template<> [[nodiscard]] inline bool ParameterView::is>() const noexcept { return this->isArray(); } [[nodiscard]] inline bool ParameterView::isByteArray() const noexcept { return this->is>(); } template<> [[nodiscard]] inline std::vector ParameterView::get() const { auto result = this->getByteArray(); if (!result.has_value()) { throw std::runtime_error(strerror(result.error())); } return result.value(); } template<> [[nodiscard]] inline std::vector ParameterView::get() const { return this->getArray(); } template<> [[nodiscard]] inline std::vector ParameterView::get() const { return this->getArray(); } template<> [[nodiscard]] inline std::vector ParameterView::get() const { return this->getArray(); } template<> [[nodiscard]] inline std::map ParameterView::get() const { return this->getDict(); } class Parameter final { public: explicit Parameter(std::string_view name); explicit Parameter(std::string_view name, double value); explicit Parameter(std::string_view name, int64_t value); explicit Parameter(std::string_view name, bool value); explicit Parameter(std::string_view name, std::string_view value); explicit Parameter(std::string_view name, const char* value) : Parameter(name, std::string_view(value)) {} explicit Parameter(std::string_view name, const uint8_t* data, size_t data_length); explicit Parameter(std::string_view name, const std::vector& bytes) : Parameter(name, reinterpret_cast(bytes.data()), bytes.size()) {} explicit Parameter(std::string_view name, const std::vector& values); explicit Parameter(std::string_view name, const std::vector& values); explicit Parameter(std::string_view name, std::map values); explicit Parameter(std::string_view name, ParameterType type, ParameterValue&& value); ~Parameter() = default; Parameter(Parameter&& other) noexcept = default; Parameter& operator=(Parameter&& other) noexcept = default; Parameter(const Parameter&) = delete; Parameter& operator=(const Parameter&) = delete; [[nodiscard]] Parameter clone() const { return this->view().clone(); } [[nodiscard]] ParameterView view() const noexcept; [[nodiscard]] std::string_view name() const noexcept { return this->view().name(); } [[nodiscard]] ParameterType type() const noexcept { return this->view().type(); } [[nodiscard]] std::optional value() const noexcept { return this->view().value(); } [[nodiscard]] bool hasValue() const noexcept { return this->view().hasValue(); }; template [[nodiscard]] bool is() const { return this->view().is(); } template [[nodiscard]] bool isArray() const noexcept { return this->view().isArray(); } template [[nodiscard]] bool isDict() const noexcept { return this->view().isDict(); } [[nodiscard]] bool isByteArray() const noexcept { return this->view().isByteArray(); } template [[nodiscard]] T get() const { return this->view().get(); } template [[nodiscard]] std::vector getArray() const { return this->view().getArray(); } template [[nodiscard]] std::map getDict() const { return this->view().getDict(); } [[nodiscard]] FoxgloveResult> getByteArray() const { return this->view().getByteArray(); } private: friend class ParameterView; friend class ParameterArray; struct Deleter { void operator()(foxglove_parameter* ptr) const noexcept; }; std::unique_ptr impl_; explicit Parameter(foxglove_parameter* param); [[nodiscard]] foxglove_parameter* release() noexcept; }; class ParameterArrayView final { public: explicit ParameterArrayView(const foxglove_parameter_array* ptr); [[nodiscard]] std::vector parameters() const; private: const foxglove_parameter_array* impl_; }; class ParameterArray final { public: explicit ParameterArray(std::vector&& params); ~ParameterArray() = default; ParameterArray(ParameterArray&& other) noexcept = default; ParameterArray& operator=(ParameterArray&& other) noexcept = default; ParameterArray(const ParameterArray&) = delete; ParameterArray& operator=(const ParameterArray&) = delete; [[nodiscard]] ParameterArrayView view() const noexcept; [[nodiscard]] std::vector parameters() const { return this->view().parameters(); } private: friend class WebSocketServer; friend class RemoteAccessGateway; struct Deleter { void operator()(foxglove_parameter_array* ptr) const noexcept; }; std::unique_ptr impl_; [[nodiscard]] foxglove_parameter_array* release() noexcept; }; } // namespace foxglove