span_context_kv_iterable_view.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #include <iterator>
  5. #include <type_traits>
  6. #include <utility>
  7. #include "opentelemetry/common/key_value_iterable_view.h"
  8. #include "opentelemetry/nostd/function_ref.h"
  9. #include "opentelemetry/nostd/span.h"
  10. #include "opentelemetry/nostd/string_view.h"
  11. #include "opentelemetry/nostd/utility.h"
  12. #include "opentelemetry/trace/span_context.h"
  13. #include "opentelemetry/trace/span_context_kv_iterable.h"
  14. #include "opentelemetry/version.h"
  15. OPENTELEMETRY_BEGIN_NAMESPACE
  16. namespace trace
  17. {
  18. // NOTE - code within `detail` namespace implements internal details, and not part
  19. // of the public interface.
  20. namespace detail
  21. {
  22. template <class T>
  23. inline void take_span_context_kv(SpanContext, opentelemetry::common::KeyValueIterableView<T>)
  24. {}
  25. template <class T, nostd::enable_if_t<common::detail::is_key_value_iterable<T>::value> * = nullptr>
  26. inline void take_span_context_kv(SpanContext, T &)
  27. {}
  28. inline void take_span_context_kv(
  29. SpanContext,
  30. std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>>)
  31. {}
  32. template <class T>
  33. auto is_span_context_kv_iterable_impl(T iterable)
  34. -> decltype(take_span_context_kv(std::begin(iterable)->first, std::begin(iterable)->second),
  35. nostd::size(iterable),
  36. std::true_type{});
  37. std::false_type is_span_context_kv_iterable_impl(...);
  38. template <class T>
  39. struct is_span_context_kv_iterable
  40. {
  41. static const bool value =
  42. decltype(detail::is_span_context_kv_iterable_impl(std::declval<T>()))::value;
  43. };
  44. } // namespace detail
  45. template <class T>
  46. class SpanContextKeyValueIterableView final : public SpanContextKeyValueIterable
  47. {
  48. static_assert(detail::is_span_context_kv_iterable<T>::value,
  49. "Must be a context/key-value iterable");
  50. public:
  51. explicit SpanContextKeyValueIterableView(const T &links) noexcept : container_{&links} {}
  52. bool ForEachKeyValue(nostd::function_ref<bool(SpanContext, const common::KeyValueIterable &)>
  53. callback) const noexcept override
  54. {
  55. auto iter = std::begin(*container_);
  56. auto last = std::end(*container_);
  57. for (; iter != last; ++iter)
  58. {
  59. if (!this->do_callback(iter->first, iter->second, callback))
  60. {
  61. return false;
  62. }
  63. }
  64. return true;
  65. }
  66. size_t size() const noexcept override { return nostd::size(*container_); }
  67. private:
  68. const T *container_;
  69. bool do_callback(SpanContext span_context,
  70. const common::KeyValueIterable &attributes,
  71. nostd::function_ref<bool(SpanContext, const common::KeyValueIterable &)>
  72. callback) const noexcept
  73. {
  74. if (!callback(span_context, attributes))
  75. {
  76. return false;
  77. }
  78. return true;
  79. }
  80. template <class U,
  81. nostd::enable_if_t<common::detail::is_key_value_iterable<U>::value> * = nullptr>
  82. bool do_callback(SpanContext span_context,
  83. const U &attributes,
  84. nostd::function_ref<bool(SpanContext, const common::KeyValueIterable &)>
  85. callback) const noexcept
  86. {
  87. return do_callback(span_context, common::KeyValueIterableView<U>(attributes), callback);
  88. }
  89. bool do_callback(
  90. SpanContext span_context,
  91. std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>> attributes,
  92. nostd::function_ref<bool(SpanContext, const common::KeyValueIterable &)> callback)
  93. const noexcept
  94. {
  95. return do_callback(span_context,
  96. nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{
  97. attributes.begin(), attributes.end()},
  98. callback);
  99. }
  100. };
  101. } // namespace trace
  102. OPENTELEMETRY_END_NAMESPACE