From cfc44919ddd4ae370a1ef47bf45fc05f0afac57a Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Wed, 16 Dec 2020 23:33:50 -0500 Subject: [PATCH] Add C++ interface for the libbabeltrace2 `bt_clock_class` API This patch adds C++ wrappers for Babeltrace 2 clock class objects. The two new available types are `bt2::ClockClass` and `bt2::ConstClockClass`. This new template class follows the approach of other wrappers in `src/cpp-common/bt2`. Because `bt2::ClockClass::userAttributes()` needs to access the libbabeltrace2 pointer of the map value, `bt2::CommonValue` makes `bt2::ClockClass` a friend. Signed-off-by: Philippe Proulx Change-Id: I40e012e1682208f2a43896be3a952cdf8ae0889b Reviewed-on: https://review.lttng.org/c/babeltrace/+/4602 --- src/cpp-common/bt2/clock-class.hpp | 290 +++++++++++++++++++++++++++++ src/cpp-common/bt2/value.hpp | 6 + 2 files changed, 296 insertions(+) create mode 100644 src/cpp-common/bt2/clock-class.hpp diff --git a/src/cpp-common/bt2/clock-class.hpp b/src/cpp-common/bt2/clock-class.hpp new file mode 100644 index 00000000..e5522096 --- /dev/null +++ b/src/cpp-common/bt2/clock-class.hpp @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2020 Philippe Proulx + * + * SPDX-License-Identifier: MIT + */ + +#ifndef BABELTRACE_CPP_COMMON_BT2_CLOCK_CLASS_HPP +#define BABELTRACE_CPP_COMMON_BT2_CLOCK_CLASS_HPP + +#include +#include +#include +#include + +#include "internal/borrowed-obj.hpp" +#include "internal/shared-obj.hpp" +#include "cpp-common/optional.hpp" +#include "cpp-common/string_view.hpp" +#include "cpp-common/uuid-view.hpp" +#include "lib-error.hpp" +#include "value.hpp" + +namespace bt2 { + +namespace internal { + +struct ClockClassRefFuncs final +{ + static void get(const bt_clock_class * const libObjPtr) + { + bt_clock_class_get_ref(libObjPtr); + } + + static void put(const bt_clock_class * const libObjPtr) + { + bt_clock_class_put_ref(libObjPtr); + } +}; + +template +struct CommonClockClassSpec; + +// Functions specific to mutable clock classes +template <> +struct CommonClockClassSpec final +{ + static bt_value *userAttributes(bt_clock_class * const libObjPtr) noexcept + { + return bt_clock_class_borrow_user_attributes(libObjPtr); + } +}; + +// Functions specific to constant clock classes +template <> +struct CommonClockClassSpec final +{ + static const bt_value *userAttributes(const bt_clock_class * const libObjPtr) noexcept + { + return bt_clock_class_borrow_user_attributes_const(libObjPtr); + } +}; + +} // namespace internal + +class ClockClassOffset final +{ +public: + explicit ClockClassOffset(const std::int64_t seconds, const std::uint64_t cycles) : + _mSeconds {seconds}, _mCycles {cycles} + { + } + + ClockClassOffset(const ClockClassOffset&) noexcept = default; + ClockClassOffset& operator=(const ClockClassOffset&) noexcept = default; + + std::int64_t seconds() const noexcept + { + return _mSeconds; + } + + std::uint64_t cycles() const noexcept + { + return _mCycles; + } + +private: + std::int64_t _mSeconds; + std::uint64_t _mCycles; +}; + +template +class CommonClockClass final : public internal::BorrowedObj +{ +private: + using typename internal::BorrowedObj::_ThisBorrowedObj; + using typename internal::BorrowedObj::_LibObjPtr; + using _ThisCommonClockClass = CommonClockClass; + +public: + using Shared = + internal::SharedObj<_ThisCommonClockClass, LibObjT, internal::ClockClassRefFuncs>; + + using UserAttributes = + typename std::conditional::value, ConstMapValue, MapValue>::type; + + explicit CommonClockClass(const _LibObjPtr libObjPtr) noexcept : _ThisBorrowedObj {libObjPtr} + { + } + + template + CommonClockClass(const CommonClockClass& clkClass) noexcept : + _ThisBorrowedObj {clkClass} + { + } + + template + _ThisCommonClockClass& operator=(const CommonClockClass& clkClass) noexcept + { + _ThisBorrowedObj::operator=(clkClass); + return *this; + } + + void frequency(const std::uint64_t frequency) noexcept + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + bt_clock_class_set_frequency(this->_libObjPtr(), frequency); + } + + std::uint64_t frequency() const noexcept + { + return bt_clock_class_get_frequency(this->_libObjPtr()); + } + + void offset(const ClockClassOffset& offset) noexcept + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + bt_clock_class_set_offset(this->_libObjPtr(), offset.seconds(), offset.cycles()); + } + + ClockClassOffset offset() const noexcept + { + std::int64_t seconds; + std::uint64_t cycles; + + bt_clock_class_get_offset(this->_libObjPtr(), &seconds, &cycles); + return ClockClassOffset {seconds, cycles}; + } + + void precision(const std::uint64_t precision) noexcept + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + bt_clock_class_set_precision(this->_libObjPtr(), precision); + } + + std::uint64_t precision() const noexcept + { + return bt_clock_class_get_precision(this->_libObjPtr()); + } + + void originIsUnixEpoch(const bool originIsUnixEpoch) noexcept + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + bt_clock_class_set_origin_is_unix_epoch(this->_libObjPtr(), + static_cast(originIsUnixEpoch)); + } + + bool originIsUnixEpoch() const noexcept + { + return static_cast(bt_clock_class_origin_is_unix_epoch(this->_libObjPtr())); + } + + void name(const char * const name) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto status = bt_clock_class_set_name(this->_libObjPtr(), name); + + if (status == BT_CLOCK_CLASS_SET_NAME_STATUS_MEMORY_ERROR) { + throw LibMemoryError {}; + } + } + + void name(const std::string& name) + { + this->name(name.data()); + } + + nonstd::optional name() const noexcept + { + const auto name = bt_clock_class_get_name(this->_libObjPtr()); + + if (name) { + return name; + } + + return nonstd::nullopt; + } + + void description(const char * const description) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + const auto status = bt_clock_class_set_description(this->_libObjPtr(), description); + + if (status == BT_CLOCK_CLASS_SET_DESCRIPTION_STATUS_MEMORY_ERROR) { + throw LibMemoryError {}; + } + } + + void description(const std::string& description) + { + this->description(description.data()); + } + + nonstd::optional description() const noexcept + { + const auto description = bt_clock_class_get_description(this->_libObjPtr()); + + if (description) { + return description; + } + + return nonstd::nullopt; + } + + void uuid(const std::uint8_t * const uuid) noexcept + { + bt_clock_class_set_uuid(this->_libObjPtr(), uuid); + } + + nonstd::optional uuid() const noexcept + { + const auto uuid = bt_clock_class_get_uuid(this->_libObjPtr()); + + if (uuid) { + return bt2_common::UuidView {uuid}; + } + + return nonstd::nullopt; + } + + template + void userAttributes(const CommonMapValue& userAttrs) + { + static_assert(!std::is_const::value, "`LibObjT` must NOT be `const`."); + + bt_clock_class_set_user_attributes(this->_libObjPtr(), userAttrs._libObjPtr()); + } + + ConstMapValue userAttributes() const noexcept + { + return ConstMapValue {internal::CommonClockClassSpec::userAttributes( + this->_libObjPtr())}; + } + + UserAttributes userAttributes() noexcept + { + return UserAttributes { + internal::CommonClockClassSpec::userAttributes(this->_libObjPtr())}; + } + + std::int64_t cyclesToNsFromOrigin(const std::uint64_t value) const + { + std::int64_t nsFromOrigin; + const auto status = + bt_clock_class_cycles_to_ns_from_origin(this->_libObjPtr(), value, &nsFromOrigin); + + if (status == BT_CLOCK_CLASS_CYCLES_TO_NS_FROM_ORIGIN_STATUS_OVERFLOW_ERROR) { + throw LibOverflowError {}; + } + + return nsFromOrigin; + } + + Shared shared() const noexcept + { + return Shared {*this}; + } +}; + +using ClockClass = CommonClockClass; +using ConstClockClass = CommonClockClass; + +} // namespace bt2 + +#endif // BABELTRACE_CPP_COMMON_BT2_CLOCK_CLASS_HPP diff --git a/src/cpp-common/bt2/value.hpp b/src/cpp-common/bt2/value.hpp index 31411183..2c4d4dab 100644 --- a/src/cpp-common/bt2/value.hpp +++ b/src/cpp-common/bt2/value.hpp @@ -79,6 +79,9 @@ enum class ValueType MAP = BT_VALUE_TYPE_MAP, }; +template +class CommonClockClass; + template class CommonValue : public internal::BorrowedObj { @@ -88,6 +91,9 @@ class CommonValue : public internal::BorrowedObj // Allow insert() to call `val._libObjPtr()` friend class CommonMapValue; + // Allow userAttributes() to call `val._libObjPtr()` + friend class CommonClockClass; + // Allow operator==() to call `other._libObjPtr()` friend class CommonValue; friend class CommonValue; -- 2.34.1