key_value_iterable_view.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #include <stddef.h>
  5. #include <initializer_list>
  6. #include <iterator>
  7. #include <type_traits>
  8. #include <utility>
  9. #include <vector>
  10. #include "opentelemetry/common/attribute_value.h"
  11. #include "opentelemetry/common/key_value_iterable.h"
  12. #include "opentelemetry/nostd/function_ref.h"
  13. #include "opentelemetry/nostd/span.h"
  14. #include "opentelemetry/nostd/string_view.h"
  15. #include "opentelemetry/nostd/type_traits.h"
  16. #include "opentelemetry/nostd/utility.h"
  17. #include "opentelemetry/version.h"
  18. OPENTELEMETRY_BEGIN_NAMESPACE
  19. namespace common
  20. {
  21. // NOTE - code within `detail` namespace implements internal details, and not part
  22. // of the public interface.
  23. namespace detail
  24. {
  25. inline void take_key_value(nostd::string_view, common::AttributeValue) {}
  26. template <class T>
  27. auto is_key_value_iterable_impl(T iterable)
  28. -> decltype(take_key_value(std::begin(iterable)->first, std::begin(iterable)->second),
  29. nostd::size(iterable),
  30. std::true_type{});
  31. std::false_type is_key_value_iterable_impl(...);
  32. template <class T>
  33. struct is_key_value_iterable
  34. {
  35. static const bool value = decltype(detail::is_key_value_iterable_impl(std::declval<T>()))::value;
  36. };
  37. } // namespace detail
  38. /**
  39. * @brief Container for key-value pairs that can transform every value in it to one of types
  40. * listed in common::AttributeValue. It may contain value types that are not directly map'able
  41. * to primitive value types. In that case the `ForEachKeyValue` method acts as a transform to
  42. * convert the value type to one listed under AtributeValue (bool, int32_t, int64_t, uint32_t,
  43. * uint64_t, double, nostd::string_view, or arrays of primite types). For example, if UUID,
  44. * GUID, or UTF-16 string type is passed as one of values stored inside this container, the
  45. * container itself may provide a custom implementation of `ForEachKeyValue` to transform the
  46. * 'non-standard' type to one of the standard types.
  47. */
  48. template <class T>
  49. class KeyValueIterableView final : public KeyValueIterable
  50. {
  51. public:
  52. explicit KeyValueIterableView(const T &container) noexcept : container_{&container} {}
  53. // KeyValueIterable
  54. bool ForEachKeyValue(nostd::function_ref<bool(nostd::string_view, common::AttributeValue)>
  55. callback) const noexcept override
  56. {
  57. auto iter = std::begin(*container_);
  58. auto last = std::end(*container_);
  59. for (; iter != last; ++iter)
  60. {
  61. if (!callback(iter->first, iter->second))
  62. {
  63. return false;
  64. }
  65. }
  66. return true;
  67. }
  68. size_t size() const noexcept override { return nostd::size(*container_); }
  69. private:
  70. const T *container_;
  71. };
  72. template <class T, nostd::enable_if_t<detail::is_key_value_iterable<T>::value> * = nullptr>
  73. KeyValueIterableView<T> MakeKeyValueIterableView(const T &container) noexcept
  74. {
  75. return KeyValueIterableView<T>(container);
  76. }
  77. /**
  78. * Utility function to help to make a attribute view from initializer_list
  79. *
  80. * @param attributes
  81. * @return nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>
  82. */
  83. inline static nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>
  84. MakeAttributes(std::initializer_list<std::pair<nostd::string_view, common::AttributeValue>>
  85. attributes) noexcept
  86. {
  87. return nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>{
  88. attributes.begin(), attributes.end()};
  89. }
  90. /**
  91. * Utility function to help to make a attribute view from a span
  92. *
  93. * @param attributes
  94. * @return nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>
  95. */
  96. inline static nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>
  97. MakeAttributes(
  98. nostd::span<const std::pair<nostd::string_view, common::AttributeValue>> attributes) noexcept
  99. {
  100. return attributes;
  101. }
  102. /**
  103. * Utility function to help to make a attribute view from a KeyValueIterable
  104. *
  105. * @param attributes
  106. * @return common::KeyValueIterable
  107. */
  108. inline static const common::KeyValueIterable &MakeAttributes(
  109. const common::KeyValueIterable &attributes) noexcept
  110. {
  111. return attributes;
  112. }
  113. /**
  114. * Utility function to help to make a attribute view from a key-value iterable object
  115. *
  116. * @param attributes
  117. * @return nostd::span<const std::pair<nostd::string_view, common::AttributeValue>>
  118. */
  119. template <
  120. class ArgumentType,
  121. nostd::enable_if_t<common::detail::is_key_value_iterable<ArgumentType>::value> * = nullptr>
  122. inline static common::KeyValueIterableView<ArgumentType> MakeAttributes(
  123. const ArgumentType &arg) noexcept
  124. {
  125. return common::KeyValueIterableView<ArgumentType>(arg);
  126. }
  127. } // namespace common
  128. OPENTELEMETRY_END_NAMESPACE