diff --git a/api/include/opentelemetry/nostd/unique_ptr.h b/api/include/opentelemetry/nostd/unique_ptr.h index b3f5e61998..3b199894a4 100644 --- a/api/include/opentelemetry/nostd/unique_ptr.h +++ b/api/include/opentelemetry/nostd/unique_ptr.h @@ -175,6 +175,12 @@ bool operator!=(std::nullptr_t, const unique_ptr &rhs) noexcept { return nullptr != rhs.get(); } + +template +unique_ptr make_unique(Args &&...args) +{ + return unique_ptr(new T(std::forward(args)...)); +} } // namespace nostd OPENTELEMETRY_END_NAMESPACE #endif /* OPENTELEMETRY_HAVE_STD_UNIQUE_PTR */ diff --git a/api/include/opentelemetry/std/unique_ptr.h b/api/include/opentelemetry/std/unique_ptr.h index 4b25b7c381..947734bd7b 100644 --- a/api/include/opentelemetry/std/unique_ptr.h +++ b/api/include/opentelemetry/std/unique_ptr.h @@ -18,5 +18,16 @@ namespace nostd template using unique_ptr = std::unique_ptr<_Types...>; +#if (defined(__cplusplus) && __cplusplus >= 201402L) || \ + (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L) +using std::make_unique; +#else +template +unique_ptr make_unique(Args &&...args) +{ + return unique_ptr(new T(std::forward(args)...)); +} +#endif + } // namespace nostd OPENTELEMETRY_END_NAMESPACE diff --git a/examples/multi_processor/main.cc b/examples/multi_processor/main.cc index d99d77de7d..3e07d732a0 100644 --- a/examples/multi_processor/main.cc +++ b/examples/multi_processor/main.cc @@ -65,7 +65,7 @@ void CleanupTracer() trace_api::Provider::SetTracerProvider(none); } -void dumpSpans(std::vector> &spans) +void dumpSpans(std::vector> &spans) { char span_buf[trace_api::SpanId::kSize * 2]; char trace_buf[trace_api::TraceId::kSize * 2]; diff --git a/exporters/memory/include/opentelemetry/exporters/memory/in_memory_data.h b/exporters/memory/include/opentelemetry/exporters/memory/in_memory_data.h index 26acba4b63..9a1ef26fcf 100644 --- a/exporters/memory/include/opentelemetry/exporters/memory/in_memory_data.h +++ b/exporters/memory/include/opentelemetry/exporters/memory/in_memory_data.h @@ -27,16 +27,16 @@ class InMemoryData /** * @param data a required unique pointer to the data to add to the CircularBuffer */ - void Add(std::unique_ptr data) noexcept { data_.Add(data); } + void Add(nostd::unique_ptr data) noexcept { data_.Add(data); } /** * @return Returns a vector of unique pointers containing all the data in the * CircularBuffer. This operation will empty the Buffer, which is why the data * is returned as unique pointers */ - std::vector> Get() noexcept + std::vector> Get() noexcept { - std::vector> res; + std::vector> res; // Pointer swap is required because the Consume function requires that the // AtomicUniquePointer be set to null @@ -44,7 +44,7 @@ class InMemoryData data_.size(), [&](opentelemetry::sdk::common::CircularBufferRange< opentelemetry::sdk::common::AtomicUniquePtr> range) noexcept { range.ForEach([&](opentelemetry::sdk::common::AtomicUniquePtr &ptr) noexcept { - std::unique_ptr swap_ptr = nullptr; + nostd::unique_ptr swap_ptr = nullptr; ptr.Swap(swap_ptr); res.push_back(std::move(swap_ptr)); return true; diff --git a/exporters/memory/include/opentelemetry/exporters/memory/in_memory_metric_data.h b/exporters/memory/include/opentelemetry/exporters/memory/in_memory_metric_data.h index 8d24c586b2..7cb2bf86e2 100644 --- a/exporters/memory/include/opentelemetry/exporters/memory/in_memory_metric_data.h +++ b/exporters/memory/include/opentelemetry/exporters/memory/in_memory_metric_data.h @@ -9,6 +9,7 @@ #include #include "opentelemetry/exporters/memory/in_memory_data.h" +#include "opentelemetry/nostd/unique_ptr.h" #include "opentelemetry/sdk/metrics/data/metric_data.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -37,7 +38,7 @@ class InMemoryMetricData InMemoryMetricData &operator=(const InMemoryMetricData &) = delete; InMemoryMetricData &operator=(InMemoryMetricData &&) = delete; - virtual void Add(std::unique_ptr resource_metrics) = 0; + virtual void Add(nostd::unique_ptr resource_metrics) = 0; }; /// An implementation of InMemoryMetricData that stores full-fidelity data points in a circular @@ -48,7 +49,7 @@ class CircularBufferInMemoryMetricData final : public InMemoryMetricData, { public: explicit CircularBufferInMemoryMetricData(size_t buffer_size); - void Add(std::unique_ptr resource_metrics) override; + void Add(nostd::unique_ptr resource_metrics) override; }; /// An implementation of InMemoryMetricData that stores only the most recent data point in each time @@ -59,7 +60,7 @@ class SimpleAggregateInMemoryMetricData final : public InMemoryMetricData using AttributeToPoint = std::map; - void Add(std::unique_ptr resource_metrics) override; + void Add(nostd::unique_ptr resource_metrics) override; const AttributeToPoint &Get(const std::string &scope, const std::string &metric); void Clear(); diff --git a/exporters/memory/include/opentelemetry/exporters/memory/in_memory_span_data.h b/exporters/memory/include/opentelemetry/exporters/memory/in_memory_span_data.h index 6eaae0663c..2230b1d47f 100644 --- a/exporters/memory/include/opentelemetry/exporters/memory/in_memory_span_data.h +++ b/exporters/memory/include/opentelemetry/exporters/memory/in_memory_span_data.h @@ -26,7 +26,7 @@ class InMemorySpanData final : public exporter::memory::InMemoryData(buffer_size) {} - std::vector> GetSpans() noexcept { return Get(); } + std::vector> GetSpans() noexcept { return Get(); } }; } // namespace memory } // namespace exporter diff --git a/exporters/memory/src/in_memory_metric_data.cc b/exporters/memory/src/in_memory_metric_data.cc index 2a77e0b5a3..451e21afa4 100644 --- a/exporters/memory/src/in_memory_metric_data.cc +++ b/exporters/memory/src/in_memory_metric_data.cc @@ -16,12 +16,12 @@ CircularBufferInMemoryMetricData::CircularBufferInMemoryMetricData(size_t buffer : InMemoryData(buffer_size) {} -void CircularBufferInMemoryMetricData::Add(std::unique_ptr resource_metrics) +void CircularBufferInMemoryMetricData::Add(nostd::unique_ptr resource_metrics) { InMemoryData::Add(std::move(resource_metrics)); } -void SimpleAggregateInMemoryMetricData::Add(std::unique_ptr resource_metrics) +void SimpleAggregateInMemoryMetricData::Add(nostd::unique_ptr resource_metrics) { for (const auto &sm : resource_metrics->scope_metric_data_) { @@ -31,7 +31,8 @@ void SimpleAggregateInMemoryMetricData::Add(std::unique_ptr res const auto &metric = m.instrument_descriptor.name_; for (const auto &pda : m.point_data_attr_) { - data_[{scope, metric}].insert({pda.attributes, pda.point_data}); + data_[std::tuple{scope, metric}].insert( + {pda.attributes, pda.point_data}); } } } @@ -41,7 +42,7 @@ const SimpleAggregateInMemoryMetricData::AttributeToPoint &SimpleAggregateInMemo const std::string &scope, const std::string &metric) { - return data_[{scope, metric}]; + return data_[std::tuple{scope, metric}]; } void SimpleAggregateInMemoryMetricData::Clear() diff --git a/exporters/memory/src/in_memory_metric_exporter_factory.cc b/exporters/memory/src/in_memory_metric_exporter_factory.cc index f2577c4e9b..cbdc858061 100644 --- a/exporters/memory/src/in_memory_metric_exporter_factory.cc +++ b/exporters/memory/src/in_memory_metric_exporter_factory.cc @@ -3,6 +3,7 @@ #include "opentelemetry/exporters/memory/in_memory_metric_exporter_factory.h" #include "opentelemetry/exporters/memory/in_memory_metric_data.h" +#include "opentelemetry/nostd/unique_ptr.h" #include "opentelemetry/sdk/common/global_log_handler.h" #include "opentelemetry/sdk/metrics/export/metric_producer.h" #include "opentelemetry/sdk/metrics/push_metric_exporter.h" @@ -49,7 +50,7 @@ class InMemoryMetricExporter final : public sdk::metrics::PushMetricExporter OTEL_INTERNAL_LOG_ERROR("[In Memory Metric Exporter] Exporting failed, exporter is shutdown"); return ExportResult::kFailure; } - data_->Add(std::make_unique(data)); + data_->Add(opentelemetry::nostd::make_unique(data)); return ExportResult::kSuccess; } @@ -78,14 +79,15 @@ class InMemoryMetricExporter final : public sdk::metrics::PushMetricExporter std::unique_ptr InMemoryMetricExporterFactory::Create( const std::shared_ptr &data) { - return Create(data, [](auto) { return AggregationTemporality::kCumulative; }); + return Create(data, + [](sdk::metrics::InstrumentType) { return AggregationTemporality::kCumulative; }); } std::unique_ptr InMemoryMetricExporterFactory::Create( const std::shared_ptr &data, const AggregationTemporalitySelector &temporality) { - return std::make_unique(data, temporality); + return std::unique_ptr(new InMemoryMetricExporter{data, temporality}); } } // namespace memory diff --git a/exporters/memory/test/in_memory_metric_data_test.cc b/exporters/memory/test/in_memory_metric_data_test.cc index ffaba2cfb9..c2df83226b 100644 --- a/exporters/memory/test/in_memory_metric_data_test.cc +++ b/exporters/memory/test/in_memory_metric_data_test.cc @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 #include "opentelemetry/exporters/memory/in_memory_metric_data.h" +#include "opentelemetry/nostd/unique_ptr.h" #include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h" #include "opentelemetry/sdk/metrics/export/metric_producer.h" #include "opentelemetry/sdk/resource/resource.h" @@ -23,7 +24,7 @@ TEST(InMemoryMetricDataTest, CircularBuffer) { CircularBufferInMemoryMetricData buf(10); Resource resource = Resource::GetEmpty(); - buf.Add(std::make_unique( + buf.Add(opentelemetry::nostd::make_unique( &resource, std::vector{{nullptr, std::vector{}}})); EXPECT_EQ((*buf.Get().begin())->resource_, &resource); } @@ -45,7 +46,7 @@ TEST(InMemoryMetricDataTest, SimpleAggregate) md.instrument_descriptor.name_ = "my-metric"; md.point_data_attr_.push_back(pda); - agg.Add(std::make_unique( + agg.Add(opentelemetry::nostd::make_unique( &resource, std::vector{{scope.get(), std::vector{md}}})); auto it = agg.Get("my-scope", "my-metric").begin(); diff --git a/sdk/include/opentelemetry/sdk/common/atomic_unique_ptr.h b/sdk/include/opentelemetry/sdk/common/atomic_unique_ptr.h index 5945df98c6..d9cc226ea3 100644 --- a/sdk/include/opentelemetry/sdk/common/atomic_unique_ptr.h +++ b/sdk/include/opentelemetry/sdk/common/atomic_unique_ptr.h @@ -6,6 +6,7 @@ #include #include +#include "opentelemetry/nostd/unique_ptr.h" #include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -25,6 +26,10 @@ class AtomicUniquePtr explicit AtomicUniquePtr(std::unique_ptr &&other) noexcept : ptr_(other.release()) {} +#if !defined(OPENTELEMETRY_HAVE_STD_UNIQUE_PTR) + explicit AtomicUniquePtr(nostd::unique_ptr &&other) noexcept : ptr_(other.release()) {} +#endif + ~AtomicUniquePtr() noexcept { Reset(); } T &operator*() const noexcept { return *Get(); } @@ -66,6 +71,33 @@ class AtomicUniquePtr */ void Swap(std::unique_ptr &other) noexcept { other.reset(ptr_.exchange(other.release())); } +#if !defined(OPENTELEMETRY_HAVE_STD_UNIQUE_PTR) + /** + * Atomically swap the pointer only if it's null. + * @param owner the pointer to swap with + * @return true if the swap was successful + */ + bool SwapIfNull(nostd::unique_ptr &owner) noexcept + { + auto ptr = owner.get(); + T *expected = nullptr; + auto was_successful = ptr_.compare_exchange_weak(expected, ptr, std::memory_order_release, + std::memory_order_relaxed); + if (was_successful) + { + owner.release(); + return true; + } + return false; + } + + /** + * Atomically swap the pointer with another. + * @param ptr the pointer to swap with + */ + void Swap(nostd::unique_ptr &other) noexcept { other.reset(ptr_.exchange(other.release())); } +#endif + /** * Set the pointer to a new value and delete the current value if non-null. * @param ptr the new pointer value to set diff --git a/sdk/include/opentelemetry/sdk/common/circular_buffer.h b/sdk/include/opentelemetry/sdk/common/circular_buffer.h index a35498ecea..9f498fd2a1 100644 --- a/sdk/include/opentelemetry/sdk/common/circular_buffer.h +++ b/sdk/include/opentelemetry/sdk/common/circular_buffer.h @@ -11,6 +11,7 @@ #include #include "opentelemetry/nostd/span.h" +#include "opentelemetry/nostd/unique_ptr.h" #include "opentelemetry/sdk/common/atomic_unique_ptr.h" #include "opentelemetry/sdk/common/circular_buffer_range.h" #include "opentelemetry/version.h" @@ -83,7 +84,7 @@ class CircularBuffer * @param ptr a pointer to the element to add * @return true if the element was successfully added; false, otherwise. */ - bool Add(std::unique_ptr &ptr) noexcept + bool Add(nostd::unique_ptr &ptr) noexcept { while (true) { @@ -118,7 +119,7 @@ class CircularBuffer } } - bool Add(std::unique_ptr &&ptr) noexcept + bool Add(nostd::unique_ptr &&ptr) noexcept { // rvalue to lvalue reference bool result = Add(std::ref(ptr)); @@ -126,6 +127,19 @@ class CircularBuffer return result; } +#if !defined(OPENTELEMETRY_HAVE_STD_UNIQUE_PTR) + bool Add(std::unique_ptr &ptr) noexcept + { + nostd::unique_ptr convert_ptr{std::move(ptr)}; + + bool result = Add(convert_ptr); + ptr.reset(convert_ptr.release()); + return result; + } + + bool Add(std::unique_ptr &&ptr) noexcept { return Add(nostd::unique_ptr{std::move(ptr)}); } +#endif + /** * Clear the circular buffer. *