From 7f835b414a673d1c54773bbdbf813b2e66fe5f90 Mon Sep 17 00:00:00 2001 From: Grant Limberg Date: Fri, 11 Jul 2025 13:12:13 -0700 Subject: [PATCH] include the otel header-only part directly for ease of use --- .../include/opentelemetry/baggage/baggage.h | 299 + .../opentelemetry/baggage/baggage_context.h | 36 + .../baggage/propagation/baggage_propagator.h | 60 + .../opentelemetry/common/attribute_value.h | 82 + .../opentelemetry/common/key_value_iterable.h | 64 + .../common/key_value_iterable_view.h | 146 + .../opentelemetry/common/kv_properties.h | 272 + .../include/opentelemetry/common/macros.h | 523 ++ .../opentelemetry/common/spin_lock_mutex.h | 133 + .../opentelemetry/common/string_util.h | 42 + .../include/opentelemetry/common/timestamp.h | 206 + .../include/opentelemetry/config.h | 19 + .../include/opentelemetry/context/context.h | 171 + .../opentelemetry/context/context_value.h | 35 + .../propagation/composite_propagator.h | 93 + .../context/propagation/global_propagator.h | 57 + .../context/propagation/noop_propagator.h | 40 + .../context/propagation/text_map_propagator.h | 59 + .../opentelemetry/context/runtime_context.h | 340 ++ .../opentelemetry/detail/preprocessor.h | 25 + .../include/opentelemetry/logs/event_id.h | 37 + .../include/opentelemetry/logs/event_logger.h | 82 + .../logs/event_logger_provider.h | 37 + .../include/opentelemetry/logs/log_record.h | 92 + .../include/opentelemetry/logs/logger.h | 492 ++ .../opentelemetry/logs/logger_provider.h | 71 + .../opentelemetry/logs/logger_type_traits.h | 204 + .../include/opentelemetry/logs/noop.h | 131 + .../include/opentelemetry/logs/provider.h | 100 + .../include/opentelemetry/logs/severity.h | 67 + .../opentelemetry/metrics/async_instruments.h | 33 + .../include/opentelemetry/metrics/meter.h | 174 + .../opentelemetry/metrics/meter_provider.h | 148 + .../include/opentelemetry/metrics/noop.h | 271 + .../opentelemetry/metrics/observer_result.h | 54 + .../include/opentelemetry/metrics/provider.h | 60 + .../opentelemetry/metrics/sync_instruments.h | 328 ++ .../include/opentelemetry/nostd/detail/all.h | 21 + .../opentelemetry/nostd/detail/decay.h | 16 + .../nostd/detail/dependent_type.h | 20 + .../opentelemetry/nostd/detail/functional.h | 66 + .../opentelemetry/nostd/detail/invoke.h | 163 + .../opentelemetry/nostd/detail/trait.h | 75 + .../nostd/detail/type_pack_element.h | 53 + .../opentelemetry/nostd/detail/valueless.h | 14 + .../nostd/detail/variant_alternative.h | 40 + .../opentelemetry/nostd/detail/variant_fwd.h | 14 + .../opentelemetry/nostd/detail/variant_size.h | 33 + .../include/opentelemetry/nostd/detail/void.h | 28 + .../opentelemetry/nostd/function_ref.h | 94 + .../nostd/internal/absl/base/attributes.h | 621 ++ .../nostd/internal/absl/base/config.h | 671 +++ .../internal/absl/base/internal/identity.h | 37 + .../absl/base/internal/inline_variable.h | 107 + .../internal/absl/base/internal/invoke.h | 188 + .../nostd/internal/absl/base/macros.h | 220 + .../nostd/internal/absl/base/optimization.h | 181 + .../nostd/internal/absl/base/options.h | 216 + .../nostd/internal/absl/base/policy_checks.h | 115 + .../nostd/internal/absl/base/port.h | 26 + .../nostd/internal/absl/meta/type_traits.h | 779 +++ .../internal/absl/types/bad_variant_access.h | 94 + .../internal/absl/types/internal/variant.h | 1649 ++++++ .../nostd/internal/absl/types/variant.h | 866 +++ .../nostd/internal/absl/utility/utility.h | 350 ++ .../include/opentelemetry/nostd/shared_ptr.h | 210 + .../include/opentelemetry/nostd/span.h | 274 + .../include/opentelemetry/nostd/string_view.h | 226 + .../include/opentelemetry/nostd/type_traits.h | 172 + .../include/opentelemetry/nostd/unique_ptr.h | 180 + .../include/opentelemetry/nostd/utility.h | 160 + .../include/opentelemetry/nostd/variant.h | 85 + .../plugin/detail/dynamic_library_handle.h | 20 + .../plugin/detail/dynamic_load_unix.h | 73 + .../plugin/detail/dynamic_load_windows.h | 96 + .../opentelemetry/plugin/detail/loader_info.h | 24 + .../plugin/detail/tracer_handle.h | 27 + .../opentelemetry/plugin/detail/utility.h | 36 + .../opentelemetry/plugin/dynamic_load.h | 30 + .../include/opentelemetry/plugin/factory.h | 65 + .../include/opentelemetry/plugin/hook.h | 51 + .../include/opentelemetry/plugin/tracer.h | 133 + .../opentelemetry/semconv/azure_metrics.h | 97 + .../opentelemetry/semconv/cicd_metrics.h | 213 + .../opentelemetry/semconv/client_attributes.h | 41 + .../opentelemetry/semconv/code_attributes.h | 81 + .../opentelemetry/semconv/container_metrics.h | 266 + .../opentelemetry/semconv/cpu_metrics.h | 141 + .../opentelemetry/semconv/db_attributes.h | 349 ++ .../opentelemetry/semconv/db_metrics.h | 53 + .../opentelemetry/semconv/dns_metrics.h | 49 + .../opentelemetry/semconv/error_attributes.h | 57 + .../semconv/exception_attributes.h | 50 + .../opentelemetry/semconv/faas_metrics.h | 287 + .../opentelemetry/semconv/gen_ai_metrics.h | 157 + .../opentelemetry/semconv/http_attributes.h | 164 + .../opentelemetry/semconv/http_metrics.h | 77 + .../opentelemetry/semconv/hw_metrics.h | 344 ++ .../semconv/incubating/app_attributes.h | 76 + .../semconv/incubating/artifact_attributes.h | 79 + .../semconv/incubating/aws_attributes.h | 425 ++ .../semconv/incubating/az_attributes.h | 37 + .../semconv/incubating/azure_attributes.h | 110 + .../semconv/incubating/azure_metrics.h | 97 + .../semconv/incubating/browser_attributes.h | 65 + .../semconv/incubating/cassandra_attributes.h | 116 + .../semconv/incubating/cicd_attributes.h | 258 + .../semconv/incubating/cicd_metrics.h | 213 + .../semconv/incubating/client_attributes.h | 41 + .../semconv/incubating/cloud_attributes.h | 287 + .../incubating/cloudevents_attributes.h | 58 + .../incubating/cloudfoundry_attributes.h | 133 + .../semconv/incubating/code_attributes.h | 126 + .../semconv/incubating/container_attributes.h | 159 + .../semconv/incubating/container_metrics.h | 266 + .../semconv/incubating/cpu_attributes.h | 78 + .../semconv/incubating/cpu_metrics.h | 141 + .../semconv/incubating/cpython_attributes.h | 48 + .../semconv/incubating/cpython_metrics.h | 154 + .../semconv/incubating/db_attributes.h | 1212 ++++ .../semconv/incubating/db_metrics.h | 861 +++ .../incubating/deployment_attributes.h | 77 + .../incubating/destination_attributes.h | 37 + .../semconv/incubating/device_attributes.h | 72 + .../semconv/incubating/disk_attributes.h | 43 + .../semconv/incubating/dns_attributes.h | 34 + .../semconv/incubating/dns_metrics.h | 49 + .../incubating/elasticsearch_attributes.h | 29 + .../semconv/incubating/enduser_attributes.h | 57 + .../semconv/incubating/error_attributes.h | 69 + .../semconv/incubating/event_attributes.h | 32 + .../semconv/incubating/exception_attributes.h | 50 + .../semconv/incubating/faas_attributes.h | 231 + .../semconv/incubating/faas_metrics.h | 287 + .../incubating/feature_flag_attributes.h | 209 + .../semconv/incubating/file_attributes.h | 143 + .../semconv/incubating/gcp_attributes.h | 221 + .../semconv/incubating/gen_ai_attributes.h | 494 ++ .../semconv/incubating/gen_ai_metrics.h | 157 + .../semconv/incubating/geo_attributes.h | 102 + .../semconv/incubating/graphql_attributes.h | 60 + .../semconv/incubating/heroku_attributes.h | 39 + .../semconv/incubating/host_attributes.h | 159 + .../semconv/incubating/http_attributes.h | 375 ++ .../semconv/incubating/http_metrics.h | 346 ++ .../semconv/incubating/hw_attributes.h | 148 + .../semconv/incubating/hw_metrics.h | 345 ++ .../semconv/incubating/k8s_attributes.h | 443 ++ .../semconv/incubating/k8s_metrics.h | 1723 ++++++ .../semconv/incubating/linux_attributes.h | 43 + .../semconv/incubating/log_attributes.h | 82 + .../semconv/incubating/message_attributes.h | 76 + .../semconv/incubating/messaging_attributes.h | 522 ++ .../semconv/incubating/messaging_metrics.h | 413 ++ .../semconv/incubating/net_attributes.h | 208 + .../semconv/incubating/network_attributes.h | 379 ++ .../semconv/incubating/oci_attributes.h | 36 + .../incubating/opentracing_attributes.h | 45 + .../semconv/incubating/os_attributes.h | 110 + .../semconv/incubating/otel_attributes.h | 202 + .../semconv/incubating/otel_metrics.h | 976 ++++ .../semconv/incubating/other_attributes.h | 47 + .../semconv/incubating/peer_attributes.h | 31 + .../semconv/incubating/pool_attributes.h | 33 + .../semconv/incubating/process_attributes.h | 297 + .../semconv/incubating/process_metrics.h | 458 ++ .../semconv/incubating/profile_attributes.h | 98 + .../semconv/incubating/rpc_attributes.h | 368 ++ .../semconv/incubating/rpc_metrics.h | 310 + .../incubating/security_rule_attributes.h | 69 + .../semconv/incubating/server_attributes.h | 41 + .../semconv/incubating/service_attributes.h | 84 + .../semconv/incubating/session_attributes.h | 34 + .../semconv/incubating/source_attributes.h | 37 + .../semconv/incubating/system_attributes.h | 383 ++ .../semconv/incubating/system_metrics.h | 1338 +++++ .../semconv/incubating/telemetry_attributes.h | 125 + .../semconv/incubating/test_attributes.h | 93 + .../semconv/incubating/thread_attributes.h | 34 + .../semconv/incubating/tls_attributes.h | 222 + .../semconv/incubating/url_attributes.h | 173 + .../incubating/user_agent_attributes.h | 92 + .../semconv/incubating/user_attributes.h | 57 + .../semconv/incubating/vcs_attributes.h | 348 ++ .../semconv/incubating/vcs_metrics.h | 435 ++ .../semconv/incubating/webengine_attributes.h | 39 + .../opentelemetry/semconv/k8s_metrics.h | 1735 ++++++ .../opentelemetry/semconv/messaging_metrics.h | 414 ++ .../semconv/network_attributes.h | 119 + .../opentelemetry/semconv/otel_attributes.h | 59 + .../opentelemetry/semconv/otel_metrics.h | 337 ++ .../opentelemetry/semconv/process_metrics.h | 458 ++ .../opentelemetry/semconv/rpc_metrics.h | 310 + .../opentelemetry/semconv/schema_url.h | 24 + .../opentelemetry/semconv/server_attributes.h | 41 + .../semconv/service_attributes.h | 41 + .../opentelemetry/semconv/system_metrics.h | 1339 +++++ .../semconv/telemetry_attributes.h | 111 + .../opentelemetry/semconv/url_attributes.h | 102 + .../semconv/user_agent_attributes.h | 30 + .../opentelemetry/semconv/vcs_metrics.h | 435 ++ .../include/opentelemetry/std/shared_ptr.h | 22 + .../include/opentelemetry/std/span.h | 71 + .../include/opentelemetry/std/string_view.h | 21 + .../include/opentelemetry/std/type_traits.h | 10 + .../include/opentelemetry/std/unique_ptr.h | 22 + .../include/opentelemetry/std/utility.h | 71 + .../include/opentelemetry/std/variant.h | 230 + .../include/opentelemetry/trace/context.h | 44 + .../opentelemetry/trace/default_span.h | 77 + .../include/opentelemetry/trace/noop.h | 159 + .../trace/propagation/b3_propagator.h | 198 + .../trace/propagation/detail/hex.h | 83 + .../trace/propagation/detail/string.h | 63 + .../trace/propagation/http_trace_context.h | 201 + .../opentelemetry/trace/propagation/jaeger.h | 127 + .../include/opentelemetry/trace/provider.h | 60 + .../include/opentelemetry/trace/scope.h | 42 + .../trace/semantic_conventions.h | 5111 +++++++++++++++++ .../include/opentelemetry/trace/span.h | 259 + .../opentelemetry/trace/span_context.h | 98 + .../trace/span_context_kv_iterable.h | 54 + .../trace/span_context_kv_iterable_view.h | 119 + .../include/opentelemetry/trace/span_id.h | 67 + .../opentelemetry/trace/span_metadata.h | 45 + .../opentelemetry/trace/span_startoptions.h | 71 + .../include/opentelemetry/trace/trace_flags.h | 66 + .../include/opentelemetry/trace/trace_id.h | 72 + .../include/opentelemetry/trace/trace_state.h | 323 ++ .../include/opentelemetry/trace/tracer.h | 244 + .../opentelemetry/trace/tracer_provider.h | 127 + .../include/opentelemetry/version.h | 29 + .../component-definitions.cmake | 41 + .../find-package-support-functions.cmake | 145 + .../opentelemetry-cpp-api-target.cmake | 108 + .../opentelemetry-cpp-config-version.cmake | 83 + .../opentelemetry-cpp-config.cmake | 252 + .../thirdparty-dependency-definitions.cmake | 36 + .../lib/pkgconfig/opentelemetry_api.pc | 15 + make-linux.mk | 5 +- make-mac.mk | 7 +- 241 files changed, 49967 insertions(+), 3 deletions(-) create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/baggage/baggage.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/baggage/baggage_context.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/baggage/propagation/baggage_propagator.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/common/attribute_value.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/common/key_value_iterable.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/common/key_value_iterable_view.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/common/kv_properties.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/common/macros.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/common/spin_lock_mutex.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/common/string_util.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/common/timestamp.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/config.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/context/context.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/context/context_value.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/context/propagation/composite_propagator.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/context/propagation/global_propagator.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/context/propagation/noop_propagator.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/context/propagation/text_map_propagator.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/context/runtime_context.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/detail/preprocessor.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/event_id.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/event_logger.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/event_logger_provider.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/log_record.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/logger.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/logger_provider.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/logger_type_traits.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/noop.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/provider.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/severity.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/async_instruments.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/meter.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/meter_provider.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/noop.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/observer_result.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/provider.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/sync_instruments.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/all.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/decay.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/dependent_type.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/functional.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/invoke.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/trait.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/type_pack_element.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/valueless.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/variant_alternative.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/variant_fwd.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/variant_size.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/void.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/function_ref.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/config.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/internal/identity.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/internal/inline_variable.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/internal/invoke.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/macros.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/optimization.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/options.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/policy_checks.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/port.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/meta/type_traits.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/types/bad_variant_access.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/types/internal/variant.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/types/variant.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/utility/utility.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/shared_ptr.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/span.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/string_view.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/type_traits.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/unique_ptr.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/utility.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/variant.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/plugin/detail/dynamic_library_handle.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/plugin/detail/dynamic_load_unix.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/plugin/detail/dynamic_load_windows.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/plugin/detail/loader_info.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/plugin/detail/tracer_handle.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/plugin/detail/utility.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/plugin/dynamic_load.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/plugin/factory.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/plugin/hook.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/plugin/tracer.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/azure_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/cicd_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/client_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/code_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/container_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/cpu_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/db_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/db_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/dns_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/error_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/exception_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/faas_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/gen_ai_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/http_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/http_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/hw_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/app_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/artifact_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/aws_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/az_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/azure_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/azure_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/browser_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/cassandra_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/cicd_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/cicd_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/client_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/cloud_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/cloudevents_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/cloudfoundry_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/code_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/container_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/container_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/cpu_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/cpu_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/cpython_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/cpython_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/db_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/db_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/deployment_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/destination_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/device_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/disk_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/dns_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/dns_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/elasticsearch_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/enduser_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/error_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/event_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/exception_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/faas_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/faas_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/feature_flag_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/file_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/gcp_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/gen_ai_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/gen_ai_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/geo_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/graphql_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/heroku_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/host_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/http_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/http_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/hw_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/hw_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/k8s_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/k8s_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/linux_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/log_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/message_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/messaging_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/messaging_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/net_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/network_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/oci_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/opentracing_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/os_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/otel_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/otel_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/other_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/peer_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/pool_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/process_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/process_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/profile_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/rpc_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/rpc_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/security_rule_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/server_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/service_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/session_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/source_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/system_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/system_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/telemetry_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/test_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/thread_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/tls_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/url_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/user_agent_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/user_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/vcs_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/vcs_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/incubating/webengine_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/k8s_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/messaging_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/network_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/otel_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/otel_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/process_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/rpc_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/schema_url.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/server_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/service_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/system_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/telemetry_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/url_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/user_agent_attributes.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/semconv/vcs_metrics.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/std/shared_ptr.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/std/span.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/std/string_view.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/std/type_traits.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/std/unique_ptr.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/std/utility.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/std/variant.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/trace/context.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/trace/default_span.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/trace/noop.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/trace/propagation/b3_propagator.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/trace/propagation/detail/hex.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/trace/propagation/detail/string.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/trace/propagation/http_trace_context.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/trace/propagation/jaeger.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/trace/provider.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/trace/scope.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/trace/semantic_conventions.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/trace/span.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/trace/span_context.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/trace/span_context_kv_iterable.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/trace/span_context_kv_iterable_view.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/trace/span_id.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/trace/span_metadata.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/trace/span_startoptions.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/trace/trace_flags.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/trace/trace_id.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/trace/trace_state.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/trace/tracer.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/trace/tracer_provider.h create mode 100644 ext/opentelemetry-cpp-api-only/include/opentelemetry/version.h create mode 100644 ext/opentelemetry-cpp-api-only/lib/cmake/opentelemetry-cpp/component-definitions.cmake create mode 100644 ext/opentelemetry-cpp-api-only/lib/cmake/opentelemetry-cpp/find-package-support-functions.cmake create mode 100644 ext/opentelemetry-cpp-api-only/lib/cmake/opentelemetry-cpp/opentelemetry-cpp-api-target.cmake create mode 100644 ext/opentelemetry-cpp-api-only/lib/cmake/opentelemetry-cpp/opentelemetry-cpp-config-version.cmake create mode 100644 ext/opentelemetry-cpp-api-only/lib/cmake/opentelemetry-cpp/opentelemetry-cpp-config.cmake create mode 100644 ext/opentelemetry-cpp-api-only/lib/cmake/opentelemetry-cpp/thirdparty-dependency-definitions.cmake create mode 100644 ext/opentelemetry-cpp-api-only/lib/pkgconfig/opentelemetry_api.pc diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/baggage/baggage.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/baggage/baggage.h new file mode 100644 index 000000000..6c799cda2 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/baggage/baggage.h @@ -0,0 +1,299 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +#include "opentelemetry/common/kv_properties.h" +#include "opentelemetry/common/macros.h" +#include "opentelemetry/nostd/shared_ptr.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE + +namespace baggage +{ + +class OPENTELEMETRY_EXPORT Baggage +{ +public: + static constexpr size_t kMaxKeyValuePairs = 180; + static constexpr size_t kMaxKeyValueSize = 4096; + static constexpr size_t kMaxSize = 8192; + static constexpr char kKeyValueSeparator = '='; + static constexpr char kMembersSeparator = ','; + static constexpr char kMetadataSeparator = ';'; + + Baggage() noexcept : kv_properties_(new common::KeyValueProperties()) {} + Baggage(size_t size) noexcept : kv_properties_(new common::KeyValueProperties(size)) {} + + template + Baggage(const T &keys_and_values) noexcept + : kv_properties_(new common::KeyValueProperties(keys_and_values)) + {} + + OPENTELEMETRY_API_SINGLETON static nostd::shared_ptr GetDefault() + { + static nostd::shared_ptr baggage{new Baggage()}; + return baggage; + } + + /* Get value for key in the baggage + @returns true if key is found, false otherwise + */ + bool GetValue(nostd::string_view key, std::string &value) const noexcept + { + return kv_properties_->GetValue(key, value); + } + + /* Returns shared_ptr of new baggage object which contains new key-value pair. If key or value is + invalid, copy of current baggage is returned + */ + nostd::shared_ptr Set(const nostd::string_view &key, + const nostd::string_view &value) noexcept + { + + nostd::shared_ptr baggage(new Baggage(kv_properties_->Size() + 1)); + const bool valid_kv = IsValidKey(key) && IsValidValue(value); + + if (valid_kv) + { + baggage->kv_properties_->AddEntry(key, value); + } + + // add rest of the fields. + kv_properties_->GetAllEntries( + [&baggage, &key, &valid_kv](nostd::string_view e_key, nostd::string_view e_value) { + // if key or value was not valid, add all the entries. Add only remaining entries + // otherwise. + if (!valid_kv || key != e_key) + { + baggage->kv_properties_->AddEntry(e_key, e_value); + } + + return true; + }); + + return baggage; + } + + // @return all key-values entries by repeatedly invoking the function reference passed as argument + // for each entry + bool GetAllEntries( + nostd::function_ref callback) const noexcept + { + return kv_properties_->GetAllEntries(callback); + } + + // delete key from the baggage if it exists. Returns shared_ptr of new baggage object. + // if key does not exist, copy of current baggage is returned. + // Validity of key is not checked as invalid keys should never be populated in baggage in the + // first place. + nostd::shared_ptr Delete(nostd::string_view key) noexcept + { + // keeping size of baggage same as key might not be found in it + nostd::shared_ptr baggage(new Baggage(kv_properties_->Size())); + kv_properties_->GetAllEntries( + [&baggage, &key](nostd::string_view e_key, nostd::string_view e_value) { + if (key != e_key) + baggage->kv_properties_->AddEntry(e_key, e_value); + return true; + }); + return baggage; + } + + // Returns shared_ptr of baggage after extracting key-value pairs from header + static nostd::shared_ptr FromHeader(nostd::string_view header) noexcept + { + if (header.size() > kMaxSize) + { + // header size exceeds maximum threshold, return empty baggage + return GetDefault(); + } + + common::KeyValueStringTokenizer kv_str_tokenizer(header); + size_t cnt = kv_str_tokenizer.NumTokens(); // upper bound on number of kv pairs + if (cnt > kMaxKeyValuePairs) + { + cnt = kMaxKeyValuePairs; + } + + nostd::shared_ptr baggage(new Baggage(cnt)); + bool kv_valid; + nostd::string_view key, value; + + while (kv_str_tokenizer.next(kv_valid, key, value) && baggage->kv_properties_->Size() < cnt) + { + if (!kv_valid || (key.size() + value.size() > kMaxKeyValueSize)) + { + // if kv pair is not valid, skip it + continue; + } + + // NOTE : metadata is kept as part of value only as it does not have any semantic meaning. + // but, we need to extract it (else Decode on value will return error) + nostd::string_view metadata; + auto metadata_separator = value.find(kMetadataSeparator); + if (metadata_separator != std::string::npos) + { + metadata = value.substr(metadata_separator); + value = value.substr(0, metadata_separator); + } + + bool err = 0; + auto key_str = UrlDecode(common::StringUtil::Trim(key), err); + auto value_str = UrlDecode(common::StringUtil::Trim(value), err); + + if (err == false && IsValidKey(key_str) && IsValidValue(value_str)) + { + if (!metadata.empty()) + { + value_str.append(metadata.data(), metadata.size()); + } + baggage->kv_properties_->AddEntry(key_str, value_str); + } + } + + return baggage; + } + + // Creates string from baggage object. + std::string ToHeader() const noexcept + { + std::string header_s; + bool first = true; + kv_properties_->GetAllEntries([&](nostd::string_view key, nostd::string_view value) { + if (!first) + { + header_s.push_back(kMembersSeparator); + } + else + { + first = false; + } + header_s.append(UrlEncode(key)); + header_s.push_back(kKeyValueSeparator); + + // extracting metadata from value. We do not encode metadata + auto metadata_separator = value.find(kMetadataSeparator); + if (metadata_separator != std::string::npos) + { + header_s.append(UrlEncode(value.substr(0, metadata_separator))); + auto metadata = value.substr(metadata_separator); + header_s.append(std::string(metadata.data(), metadata.size())); + } + else + { + header_s.append(UrlEncode(value)); + } + return true; + }); + return header_s; + } + +private: + static bool IsPrintableString(nostd::string_view str) + { + for (const auto ch : str) + { + if (ch < ' ' || ch > '~') + { + return false; + } + } + + return true; + } + + static bool IsValidKey(nostd::string_view key) { return key.size() && IsPrintableString(key); } + + static bool IsValidValue(nostd::string_view value) { return IsPrintableString(value); } + + // Uri encode key value pairs before injecting into header + // Implementation inspired from : https://golang.org/src/net/url/url.go?s=7851:7884#L264 + static std::string UrlEncode(nostd::string_view str) + { + auto to_hex = [](char c) -> char { + static const char *hex = "0123456789ABCDEF"; + return hex[c & 15]; + }; + + std::string ret; + + for (auto c : str) + { + if (std::isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') + { + ret.push_back(c); + } + else if (c == ' ') + { + ret.push_back('+'); + } + else + { + ret.push_back('%'); + ret.push_back(to_hex(c >> 4)); + ret.push_back(to_hex(c & 15)); + } + } + + return ret; + } + + // Uri decode key value pairs after extracting from header + static std::string UrlDecode(nostd::string_view str, bool &err) + { + auto IsHex = [](char c) { + return std::isdigit(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); + }; + + auto from_hex = [](char c) -> char { + // c - '0' produces integer type which could trigger error/warning when casting to char, + // but the cast is safe here. + return static_cast(std::isdigit(c) ? c - '0' : std::toupper(c) - 'A' + 10); + }; + + std::string ret; + + for (size_t i = 0; i < str.size(); i++) + { + if (str[i] == '%') + { + if (i + 2 >= str.size() || !IsHex(str[i + 1]) || !IsHex(str[i + 2])) + { + err = 1; + return ""; + } + ret.push_back(from_hex(str[i + 1]) << 4 | from_hex(str[i + 2])); + i += 2; + } + else if (str[i] == '+') + { + ret.push_back(' '); + } + else if (std::isalnum(str[i]) || str[i] == '-' || str[i] == '_' || str[i] == '.' || + str[i] == '~') + { + ret.push_back(str[i]); + } + else + { + err = 1; + return ""; + } + } + + return ret; + } + +private: + // Store entries in a C-style array to avoid using std::array or std::vector. + nostd::unique_ptr kv_properties_; +}; + +} // namespace baggage + +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/baggage/baggage_context.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/baggage/baggage_context.h new file mode 100644 index 000000000..a0016353b --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/baggage/baggage_context.h @@ -0,0 +1,36 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/baggage/baggage.h" +#include "opentelemetry/context/context.h" +#include "opentelemetry/nostd/shared_ptr.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE + +namespace baggage +{ + +static const std::string kBaggageHeader = "baggage"; + +inline nostd::shared_ptr GetBaggage(const context::Context &context) noexcept +{ + context::ContextValue context_value = context.GetValue(kBaggageHeader); + if (nostd::holds_alternative>(context_value)) + { + return nostd::get>(context_value); + } + static nostd::shared_ptr empty_baggage{new Baggage()}; + return empty_baggage; +} + +inline context::Context SetBaggage(context::Context &context, + const nostd::shared_ptr &baggage) noexcept +{ + return context.SetValue(kBaggageHeader, baggage); +} + +} // namespace baggage +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/baggage/propagation/baggage_propagator.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/baggage/propagation/baggage_propagator.h new file mode 100644 index 000000000..d75409ed6 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/baggage/propagation/baggage_propagator.h @@ -0,0 +1,60 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include + +#include "opentelemetry/baggage/baggage.h" +#include "opentelemetry/baggage/baggage_context.h" +#include "opentelemetry/context/context.h" +#include "opentelemetry/context/propagation/text_map_propagator.h" +#include "opentelemetry/nostd/function_ref.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace baggage +{ +namespace propagation +{ + +class BaggagePropagator : public context::propagation::TextMapPropagator +{ +public: + void Inject(context::propagation::TextMapCarrier &carrier, + const context::Context &context) noexcept override + { + auto baggage = baggage::GetBaggage(context); + auto header = baggage->ToHeader(); + if (header.size()) + { + carrier.Set(kBaggageHeader, header); + } + } + + context::Context Extract(const context::propagation::TextMapCarrier &carrier, + context::Context &context) noexcept override + { + nostd::string_view baggage_str = carrier.Get(baggage::kBaggageHeader); + auto baggage = baggage::Baggage::FromHeader(baggage_str); + + if (baggage->ToHeader().size()) + { + return baggage::SetBaggage(context, baggage); + } + else + { + return context; + } + } + + bool Fields(nostd::function_ref callback) const noexcept override + { + return callback(kBaggageHeader); + } +}; +} // namespace propagation +} // namespace baggage +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/attribute_value.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/attribute_value.h new file mode 100644 index 000000000..af4cc83d4 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/attribute_value.h @@ -0,0 +1,82 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +#include "opentelemetry/nostd/span.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/nostd/variant.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace common +{ +/// OpenTelemetry signals can be enriched by adding attributes. The +/// \c AttributeValue type is defined as a variant of all attribute value +/// types the OpenTelemetry C++ API supports. +/// +/// The following attribute value types are supported by the OpenTelemetry +/// specification: +/// - Primitive types: string, boolean, double precision floating point +/// (IEEE 754-1985) or signed 64 bit integer. +/// - Homogenous arrays of primitive type values. +/// +/// \warning +/// \parblock The OpenTelemetry C++ API currently supports several attribute +/// value types that are not covered by the OpenTelemetry specification: +/// - \c uint64_t +/// - \c nostd::span +/// - \c nostd::span +/// +/// Those types are reserved for future use and currently should not be +/// used. There are no guarantees around how those values are handled by +/// exporters. +/// \endparblock +using AttributeValue = + nostd::variant, + nostd::span, + nostd::span, + nostd::span, + nostd::span, + nostd::span, + // Not currently supported by the specification, but reserved for future use. + // Added to provide support for all primitive C++ types. + uint64_t, + // Not currently supported by the specification, but reserved for future use. + // Added to provide support for all primitive C++ types. + nostd::span, + // Not currently supported by the specification, but reserved for future use. + // See https://github.com/open-telemetry/opentelemetry-specification/issues/780 + nostd::span>; + +enum AttributeType +{ + kTypeBool, + kTypeInt, + kTypeInt64, + kTypeUInt, + kTypeDouble, + kTypeCString, + kTypeString, + kTypeSpanBool, + kTypeSpanInt, + kTypeSpanInt64, + kTypeSpanUInt, + kTypeSpanDouble, + kTypeSpanString, + kTypeUInt64, + kTypeSpanUInt64, + kTypeSpanByte +}; + +} // namespace common +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/key_value_iterable.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/key_value_iterable.h new file mode 100644 index 000000000..9d43e1571 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/key_value_iterable.h @@ -0,0 +1,64 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/common/attribute_value.h" +#include "opentelemetry/nostd/function_ref.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace common +{ +/** + * Supports internal iteration over a collection of key-value pairs. + */ +class KeyValueIterable +{ +public: + virtual ~KeyValueIterable() = default; + + /** + * Iterate over key-value pairs + * @param callback a callback to invoke for each key-value. If the callback returns false, + * the iteration is aborted. + * @return true if every key-value pair was iterated over + */ + virtual bool ForEachKeyValue(nostd::function_ref + callback) const noexcept = 0; + + /** + * @return the number of key-value pairs + */ + virtual size_t size() const noexcept = 0; +}; + +/** + * Supports internal iteration over a collection of key-value pairs. + */ +class NoopKeyValueIterable : public KeyValueIterable +{ +public: + ~NoopKeyValueIterable() override = default; + + /** + * Iterate over key-value pairs + * @param callback a callback to invoke for each key-value. If the callback returns false, + * the iteration is aborted. + * @return true if every key-value pair was iterated over + */ + bool ForEachKeyValue( + nostd::function_ref) const noexcept override + { + return true; + } + + /** + * @return the number of key-value pairs + */ + size_t size() const noexcept override { return 0; } +}; + +} // namespace common +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/key_value_iterable_view.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/key_value_iterable_view.h new file mode 100644 index 000000000..e22fb6f06 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/key_value_iterable_view.h @@ -0,0 +1,146 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "opentelemetry/common/attribute_value.h" +#include "opentelemetry/common/key_value_iterable.h" +#include "opentelemetry/nostd/function_ref.h" +#include "opentelemetry/nostd/span.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/nostd/type_traits.h" +#include "opentelemetry/nostd/utility.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace common +{ +// NOTE - code within `detail` namespace implements internal details, and not part +// of the public interface. +namespace detail +{ +inline void take_key_value(nostd::string_view, common::AttributeValue) {} + +template +auto is_key_value_iterable_impl(T iterable) + -> decltype(take_key_value(std::begin(iterable)->first, std::begin(iterable)->second), + nostd::size(iterable), + std::true_type{}); + +std::false_type is_key_value_iterable_impl(...); + +template +struct is_key_value_iterable +{ + static const bool value = decltype(detail::is_key_value_iterable_impl(std::declval()))::value; +}; +} // namespace detail + +/** + * @brief Container for key-value pairs that can transform every value in it to one of types + * listed in common::AttributeValue. It may contain value types that are not directly map'able + * to primitive value types. In that case the `ForEachKeyValue` method acts as a transform to + * convert the value type to one listed under AtributeValue (bool, int32_t, int64_t, uint32_t, + * uint64_t, double, nostd::string_view, or arrays of primite types). For example, if UUID, + * GUID, or UTF-16 string type is passed as one of values stored inside this container, the + * container itself may provide a custom implementation of `ForEachKeyValue` to transform the + * 'non-standard' type to one of the standard types. + */ +template +class KeyValueIterableView final : public KeyValueIterable +{ + +public: + explicit KeyValueIterableView(const T &container) noexcept : container_{&container} {} + + // KeyValueIterable + bool ForEachKeyValue(nostd::function_ref + callback) const noexcept override + { + auto iter = std::begin(*container_); + auto last = std::end(*container_); + for (; iter != last; ++iter) + { + if (!callback(iter->first, iter->second)) + { + return false; + } + } + return true; + } + + size_t size() const noexcept override { return nostd::size(*container_); } + +private: + const T *container_; +}; + +template ::value> * = nullptr> +KeyValueIterableView MakeKeyValueIterableView(const T &container) noexcept +{ + return KeyValueIterableView(container); +} + +/** + * Utility function to help to make a attribute view from initializer_list + * + * @param attributes + * @return nostd::span> + */ +inline static nostd::span> +MakeAttributes(std::initializer_list> + attributes) noexcept +{ + return nostd::span>{ + attributes.begin(), attributes.end()}; +} + +/** + * Utility function to help to make a attribute view from a span + * + * @param attributes + * @return nostd::span> + */ +inline static nostd::span> +MakeAttributes( + nostd::span> attributes) noexcept +{ + return attributes; +} + +/** + * Utility function to help to make a attribute view from a KeyValueIterable + * + * @param attributes + * @return common::KeyValueIterable + */ +inline static const common::KeyValueIterable &MakeAttributes( + const common::KeyValueIterable &attributes) noexcept +{ + return attributes; +} + +/** + * Utility function to help to make a attribute view from a key-value iterable object + * + * @param attributes + * @return nostd::span> + */ +template < + class ArgumentType, + nostd::enable_if_t::value> * = nullptr> +inline static common::KeyValueIterableView MakeAttributes( + const ArgumentType &arg) noexcept +{ + return common::KeyValueIterableView(arg); +} + +} // namespace common +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/kv_properties.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/kv_properties.h new file mode 100644 index 000000000..b5accab40 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/kv_properties.h @@ -0,0 +1,272 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/common/key_value_iterable_view.h" +#include "opentelemetry/common/string_util.h" +#include "opentelemetry/nostd/function_ref.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/nostd/unique_ptr.h" +#include "opentelemetry/version.h" + +#include +#include +#include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace common +{ + +// Constructor parameter for KeyValueStringTokenizer +struct KeyValueStringTokenizerOptions +{ + char member_separator = ','; + char key_value_separator = '='; + bool ignore_empty_members = true; +}; + +// Tokenizer for key-value headers +class KeyValueStringTokenizer +{ +public: + KeyValueStringTokenizer( + nostd::string_view str, + const KeyValueStringTokenizerOptions &opts = KeyValueStringTokenizerOptions()) noexcept + : str_(str), opts_(opts), index_(0) + {} + + static nostd::string_view GetDefaultKeyOrValue() + { + static std::string default_str = ""; + return default_str; + } + + // Returns next key value in the string header + // @param valid_kv : if the found kv pair is valid or not + // @param key : key in kv pair + // @param key : value in kv pair + // @returns true if next kv pair was found, false otherwise. + bool next(bool &valid_kv, nostd::string_view &key, nostd::string_view &value) noexcept + { + valid_kv = true; + while (index_ < str_.size()) + { + bool is_empty_pair = false; + size_t end = str_.find(opts_.member_separator, index_); + if (end == std::string::npos) + { + end = str_.size() - 1; + } + else if (end == index_) // empty pair. do not update end + { + is_empty_pair = true; + } + else + { + end--; + } + + auto list_member = StringUtil::Trim(str_, index_, end); + if (list_member.size() == 0 || is_empty_pair) + { + // empty list member + index_ = end + 2 - is_empty_pair; + if (opts_.ignore_empty_members) + { + continue; + } + + valid_kv = true; + key = GetDefaultKeyOrValue(); + value = GetDefaultKeyOrValue(); + return true; + } + + auto key_end_pos = list_member.find(opts_.key_value_separator); + if (key_end_pos == std::string::npos) + { + // invalid member + valid_kv = false; + } + else + { + key = list_member.substr(0, key_end_pos); + value = list_member.substr(key_end_pos + 1); + } + + index_ = end + 2; + + return true; + } + + // no more entries remaining + return false; + } + + // Returns total number of tokens in header string + size_t NumTokens() const noexcept + { + size_t cnt = 0, begin = 0; + while (begin < str_.size()) + { + ++cnt; + size_t end = str_.find(opts_.member_separator, begin); + if (end == std::string::npos) + { + break; + } + + begin = end + 1; + } + + return cnt; + } + + // Resets the iterator + void reset() noexcept { index_ = 0; } + +private: + nostd::string_view str_; + KeyValueStringTokenizerOptions opts_; + size_t index_; +}; + +// Class to store fixed size array of key-value pairs of string type +class KeyValueProperties +{ + // Class to store key-value pairs of string types +public: + class Entry + { + public: + Entry() : key_(nullptr), value_(nullptr) {} + + // Copy constructor + Entry(const Entry ©) + { + key_ = CopyStringToPointer(copy.key_.get()); + value_ = CopyStringToPointer(copy.value_.get()); + } + + // Copy assignment operator + Entry &operator=(Entry &other) + { + key_ = CopyStringToPointer(other.key_.get()); + value_ = CopyStringToPointer(other.value_.get()); + return *this; + } + + // Move contructor and assignment operator + Entry(Entry &&other) = default; + Entry &operator=(Entry &&other) = default; + + // Creates an Entry for a given key-value pair. + Entry(nostd::string_view key, nostd::string_view value) + { + key_ = CopyStringToPointer(key); + value_ = CopyStringToPointer(value); + } + + // Gets the key associated with this entry. + nostd::string_view GetKey() const noexcept { return key_.get(); } + + // Gets the value associated with this entry. + nostd::string_view GetValue() const noexcept { return value_.get(); } + + // Sets the value for this entry. This overrides the previous value. + void SetValue(nostd::string_view value) noexcept { value_ = CopyStringToPointer(value); } + + private: + // Store key and value as raw char pointers to avoid using std::string. + nostd::unique_ptr key_; + nostd::unique_ptr value_; + + // Copies string into a buffer and returns a unique_ptr to the buffer. + // This is a workaround for the fact that memcpy doesn't accept a const destination. + nostd::unique_ptr CopyStringToPointer(nostd::string_view str) + { + char *temp = new char[str.size() + 1]; + memcpy(temp, str.data(), str.size()); + temp[str.size()] = '\0'; + return nostd::unique_ptr(temp); + } + }; + + // Maintain the number of entries in entries_. + size_t num_entries_; + + // Max size of allocated array + size_t max_num_entries_; + + // Store entries in a C-style array to avoid using std::array or std::vector. + nostd::unique_ptr entries_; + +public: + // Create Key-value list of given size + // @param size : Size of list. + KeyValueProperties(size_t size) noexcept + : num_entries_(0), max_num_entries_(size), entries_(new Entry[size]) + {} + + // Create Empty Key-Value list + KeyValueProperties() noexcept : num_entries_(0), max_num_entries_(0), entries_(nullptr) {} + + template ::value>::type> + KeyValueProperties(const T &keys_and_values) noexcept + : num_entries_(0), + max_num_entries_(keys_and_values.size()), + entries_(new Entry[max_num_entries_]) + { + for (auto &e : keys_and_values) + { + Entry entry(e.first, e.second); + (entries_.get())[num_entries_++] = std::move(entry); + } + } + + // Adds new kv pair into kv properties + void AddEntry(nostd::string_view key, nostd::string_view value) noexcept + { + if (num_entries_ < max_num_entries_) + { + Entry entry(key, value); + (entries_.get())[num_entries_++] = std::move(entry); + } + } + + // Returns all kv pair entries + bool GetAllEntries( + nostd::function_ref callback) const noexcept + { + for (size_t i = 0; i < num_entries_; i++) + { + auto &entry = (entries_.get())[i]; + if (!callback(entry.GetKey(), entry.GetValue())) + { + return false; + } + } + return true; + } + + // Return value for key if exists, return false otherwise + bool GetValue(nostd::string_view key, std::string &value) const noexcept + { + for (size_t i = 0; i < num_entries_; i++) + { + auto &entry = (entries_.get())[i]; + if (entry.GetKey() == key) + { + const auto &entry_value = entry.GetValue(); + value = std::string(entry_value.data(), entry_value.size()); + return true; + } + } + return false; + } + + size_t Size() const noexcept { return num_entries_; } +}; +} // namespace common +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/macros.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/macros.h new file mode 100644 index 000000000..71d12a57b --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/macros.h @@ -0,0 +1,523 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +/* + OPENTELEMETRY_HAVE_BUILTIN&OPENTELEMETRY_HAVE_FEATURE + + Checks whether the compiler supports a Clang Feature Checking Macro, and if + so, checks whether it supports the provided builtin function "x" where x + is one of the functions noted in + https://clang.llvm.org/docs/LanguageExtensions.html + + Note: Use this macro to avoid an extra level of #ifdef __has_builtin check. + http://releases.llvm.org/3.3/tools/clang/docs/LanguageExtensions.html +*/ +#if !defined(OPENTELEMETRY_HAVE_BUILTIN) +# ifdef __has_builtin +# define OPENTELEMETRY_HAVE_BUILTIN(x) __has_builtin(x) +# else +# define OPENTELEMETRY_HAVE_BUILTIN(x) 0 +# endif +#endif + +#if !defined(OPENTELEMETRY_HAVE_FEATURE) +# ifdef __has_feature +# define OPENTELEMETRY_HAVE_FEATURE(f) __has_feature(f) +# else +# define OPENTELEMETRY_HAVE_FEATURE(f) 0 +# endif +#endif + +/* + has feature + + OPENTELEMETRY_HAVE_ATTRIBUTE + + A function-like feature checking macro that is a wrapper around + `__has_attribute`, which is defined by GCC 5+ and Clang and evaluates to a + nonzero constant integer if the attribute is supported or 0 if not. + + It evaluates to zero if `__has_attribute` is not defined by the compiler. + + GCC: https://gcc.gnu.org/gcc-5/changes.html + Clang: https://clang.llvm.org/docs/LanguageExtensions.html +*/ +#if !defined(OPENTELEMETRY_HAVE_ATTRIBUTE) +# ifdef __has_attribute +# define OPENTELEMETRY_HAVE_ATTRIBUTE(x) __has_attribute(x) +# else +# define OPENTELEMETRY_HAVE_ATTRIBUTE(x) 0 +# endif +#endif + +/* + OPENTELEMETRY_HAVE_CPP_ATTRIBUTE + + A function-like feature checking macro that accepts C++11 style attributes. + It's a wrapper around `__has_cpp_attribute`, defined by ISO C++ SD-6 + (https://en.cppreference.com/w/cpp/experimental/feature_test). If we don't + find `__has_cpp_attribute`, will evaluate to 0. +*/ +#if !defined(OPENTELEMETRY_HAVE_CPP_ATTRIBUTE) +# if defined(__cplusplus) && defined(__has_cpp_attribute) +// NOTE: requiring __cplusplus above should not be necessary, but +// works around https://bugs.llvm.org/show_bug.cgi?id=23435. +# define OPENTELEMETRY_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +# else +# define OPENTELEMETRY_HAVE_CPP_ATTRIBUTE(x) 0 +# endif +#endif + +/* + Expected usage pattern: + + if OPENTELEMETRY_LIKELY_CONDITION (ptr != nullptr) + { + do_something_likely(); + } else { + do_something_unlikely(); + } + + This pattern works with gcc/clang and __builtin_expect(), + as well as with C++20. + It is unclear if __builtin_expect() will be deprecated + in favor of C++20 [[likely]] or not. + + OPENTELEMETRY_LIKELY_CONDITION is preferred over OPENTELEMETRY_LIKELY, + to be revisited when C++20 is required. +*/ + +#if !defined(OPENTELEMETRY_LIKELY_CONDITION) && defined(__cplusplus) +// Only use likely with C++20 +# if __cplusplus >= 202002L +// GCC 9 has likely attribute but do not support declare it at the beginning of statement +# if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9) +# if __has_cpp_attribute(likely) +# define OPENTELEMETRY_LIKELY_CONDITION(C) (C) [[likely]] +# endif +# endif +# endif +#endif +#if !defined(OPENTELEMETRY_LIKELY_CONDITION) && (defined(__clang__) || defined(__GNUC__)) +// Only use if supported by the compiler +# define OPENTELEMETRY_LIKELY_CONDITION(C) (__builtin_expect(!!(C), true)) +#endif +#ifndef OPENTELEMETRY_LIKELY_CONDITION +// Do not use likely annotations +# define OPENTELEMETRY_LIKELY_CONDITION(C) (C) +#endif + +#if !defined(OPENTELEMETRY_UNLIKELY_CONDITION) && defined(__cplusplus) +// Only use unlikely with C++20 +# if __cplusplus >= 202002L +// GCC 9 has unlikely attribute but do not support declare it at the beginning of statement +# if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9) +# if __has_cpp_attribute(unlikely) +# define OPENTELEMETRY_UNLIKELY_CONDITION(C) (C) [[unlikely]] +# endif +# endif +# endif +#endif +#if !defined(OPENTELEMETRY_UNLIKELY_CONDITION) && (defined(__clang__) || defined(__GNUC__)) +// Only use if supported by the compiler +# define OPENTELEMETRY_UNLIKELY_CONDITION(C) (__builtin_expect(!!(C), false)) +#endif +#ifndef OPENTELEMETRY_UNLIKELY_CONDITION +// Do not use unlikely annotations +# define OPENTELEMETRY_UNLIKELY_CONDITION(C) (C) +#endif + +/* + Expected usage pattern: + + if (ptr != nullptr) + OPENTELEMETRY_LIKELY + { + do_something_likely(); + } else { + do_something_unlikely(); + } + + This pattern works starting with C++20. + See https://en.cppreference.com/w/cpp/language/attributes/likely + + Please use OPENTELEMETRY_LIKELY_CONDITION instead for now. +*/ + +#if !defined(OPENTELEMETRY_LIKELY) && defined(__cplusplus) +// Only use likely with C++20 +# if __cplusplus >= 202002L +// GCC 9 has likely attribute but do not support declare it at the beginning of statement +# if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9) +# if __has_cpp_attribute(likely) +# define OPENTELEMETRY_LIKELY [[likely]] +# endif +# endif +# endif +#endif + +#ifndef OPENTELEMETRY_LIKELY +# define OPENTELEMETRY_LIKELY +#endif + +#if !defined(OPENTELEMETRY_UNLIKELY) && defined(__cplusplus) +// Only use unlikely with C++20 +# if __cplusplus >= 202002L +// GCC 9 has unlikely attribute but do not support declare it at the beginning of statement +# if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9) +# if __has_cpp_attribute(unlikely) +# define OPENTELEMETRY_UNLIKELY [[unlikely]] +# endif +# endif +# endif +#endif + +#ifndef OPENTELEMETRY_UNLIKELY +# define OPENTELEMETRY_UNLIKELY +#endif + +/// \brief Declare variable as maybe unused +/// usage: +/// OPENTELEMETRY_MAYBE_UNUSED int a; +/// class OPENTELEMETRY_MAYBE_UNUSED a; +/// OPENTELEMETRY_MAYBE_UNUSED int a(); +/// +#if defined(__cplusplus) && __cplusplus >= 201703L +# define OPENTELEMETRY_MAYBE_UNUSED [[maybe_unused]] +#elif defined(__clang__) +# define OPENTELEMETRY_MAYBE_UNUSED __attribute__((unused)) +#elif defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) +# define OPENTELEMETRY_MAYBE_UNUSED __attribute__((unused)) +#elif (defined(_MSC_VER) && _MSC_VER >= 1910) && (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +# define OPENTELEMETRY_MAYBE_UNUSED [[maybe_unused]] +#else +# define OPENTELEMETRY_MAYBE_UNUSED +#endif + +#ifndef OPENTELEMETRY_RTTI_ENABLED +# if defined(__clang__) +# if __has_feature(cxx_rtti) +# define OPENTELEMETRY_RTTI_ENABLED +# endif +# elif defined(__GNUG__) +# if defined(__GXX_RTTI) +# define OPENTELEMETRY_RTTI_ENABLED +# endif +# elif defined(_MSC_VER) +# if defined(_CPPRTTI) +# define OPENTELEMETRY_RTTI_ENABLED +# endif +# endif +#endif + +#if defined(__cplusplus) && __cplusplus >= 201402L +# define OPENTELEMETRY_DEPRECATED [[deprecated]] +#elif defined(__clang__) +# define OPENTELEMETRY_DEPRECATED __attribute__((deprecated)) +#elif defined(__GNUC__) +# define OPENTELEMETRY_DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) +# if _MSC_VER >= 1910 && defined(_MSVC_LANG) && _MSVC_LANG >= 201703L +# define OPENTELEMETRY_DEPRECATED [[deprecated]] +# else +# define OPENTELEMETRY_DEPRECATED __declspec(deprecated) +# endif +#else +# define OPENTELEMETRY_DEPRECATED +#endif + +#if defined(__cplusplus) && __cplusplus >= 201402L +# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) [[deprecated(msg)]] +#elif defined(__clang__) +# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) __attribute__((deprecated(msg))) +#elif defined(__GNUC__) +# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) __attribute__((deprecated(msg))) +#elif defined(_MSC_VER) +# if _MSC_VER >= 1910 && defined(_MSVC_LANG) && _MSVC_LANG >= 201703L +# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) [[deprecated(msg)]] +# else +# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) __declspec(deprecated(msg)) +# endif +#else +# define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) +#endif + +// Regex support +#if (__GNUC__ == 4 && (__GNUC_MINOR__ == 8 || __GNUC_MINOR__ == 9)) +# define OPENTELEMETRY_HAVE_WORKING_REGEX 0 +#else +# define OPENTELEMETRY_HAVE_WORKING_REGEX 1 +#endif + +/* clang-format off */ + +/** + @page HEADER_ONLY_SINGLETON Header only singleton. + + @section ELF_SINGLETON + + For clang and gcc, the desired coding pattern is as follows. + + @verbatim + class Foo + { + // (a) + __attribute__((visibility("default"))) + // (b) + T& get_singleton() + { + // (c) + static T singleton; + return singleton; + } + }; + @endverbatim + + (a) is needed when the code is build with + @code -fvisibility="hidden" @endcode + to ensure that all instances of (b) are visible to the linker. + + What is duplicated in the binary is @em code, in (b). + + The linker will make sure only one instance + of all the (b) methods is used. + + (c) is a singleton implemented inside a method. + + This is very desirable, because: + + - the C++ compiler guarantees that construction + of the variable (c) is thread safe. + + - constructors for (c) singletons are executed in code path order, + or not at all if the singleton is never used. + + @section OTHER_SINGLETON + + For other platforms, header only singletons are not supported at this +point. + + @section CODING_PATTERN + + The coding pattern to use in the source code is as follows + + @verbatim + class Foo + { + OPENTELEMETRY_API_SINGLETON + T& get_singleton() + { + static T singleton; + return singleton; + } + }; + @endverbatim +*/ + +/* clang-format on */ + +#if defined(__clang__) + +# define OPENTELEMETRY_API_SINGLETON __attribute__((visibility("default"))) +# define OPENTELEMETRY_LOCAL_SYMBOL __attribute__((visibility("hidden"))) + +#elif defined(__GNUC__) + +# define OPENTELEMETRY_API_SINGLETON __attribute__((visibility("default"))) +# define OPENTELEMETRY_LOCAL_SYMBOL __attribute__((visibility("hidden"))) + +#else + +/* Add support for other compilers here. */ + +# define OPENTELEMETRY_API_SINGLETON +# define OPENTELEMETRY_LOCAL_SYMBOL + +#endif + +// +// Atomic wrappers based on compiler intrinsics for memory read/write. +// The tailing number is read/write length in bits. +// +// N.B. Compiler intrinsic is used because the usage of C++ standard library is restricted in the +// OpenTelemetry C++ API. +// +#if defined(__GNUC__) + +# define OPENTELEMETRY_ATOMIC_READ_8(ptr) __atomic_load_n(ptr, __ATOMIC_SEQ_CST) +# define OPENTELEMETRY_ATOMIC_WRITE_8(ptr, value) __atomic_store_n(ptr, value, __ATOMIC_SEQ_CST) + +#elif defined(_MSC_VER) + +# include + +# define OPENTELEMETRY_ATOMIC_READ_8(ptr) \ + static_cast(_InterlockedCompareExchange8(reinterpret_cast(ptr), 0, 0)) +# define OPENTELEMETRY_ATOMIC_WRITE_8(ptr, value) \ + _InterlockedExchange8(reinterpret_cast(ptr), static_cast(value)) + +#else +# error port atomics read/write for the current platform +#endif + +/* clang-format on */ +// +// The if/elif order matters here. If both OPENTELEMETRY_BUILD_IMPORT_DLL and +// OPENTELEMETRY_BUILD_EXPORT_DLL are defined, the former takes precedence. +// +// TODO: consider define OPENTELEMETRY_EXPORT for cygwin/gcc, see below link. +// https://gcc.gnu.org/wiki/Visibility#How_to_use_the_new_C.2B-.2B-_visibility_support +// +#if defined(_MSC_VER) && defined(OPENTELEMETRY_BUILD_IMPORT_DLL) + +# define OPENTELEMETRY_EXPORT __declspec(dllimport) + +#elif defined(_MSC_VER) && defined(OPENTELEMETRY_BUILD_EXPORT_DLL) + +# define OPENTELEMETRY_EXPORT __declspec(dllexport) + +#else + +// +// build OpenTelemetry as static library or not on Windows. +// +# define OPENTELEMETRY_EXPORT + +#endif + +// OPENTELEMETRY_HAVE_EXCEPTIONS +// +// Checks whether the compiler both supports and enables exceptions. Many +// compilers support a "no exceptions" mode that disables exceptions. +// +// Generally, when OPENTELEMETRY_HAVE_EXCEPTIONS is not defined: +// +// * Code using `throw` and `try` may not compile. +// * The `noexcept` specifier will still compile and behave as normal. +// * The `noexcept` operator may still return `false`. +// +// For further details, consult the compiler's documentation. +#ifndef OPENTELEMETRY_HAVE_EXCEPTIONS +# if defined(__clang__) && ((__clang_major__ * 100) + __clang_minor__) < 306 +// Clang < 3.6 +// http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro +# if defined(__EXCEPTIONS) && OPENTELEMETRY_HAVE_FEATURE(cxx_exceptions) +# define OPENTELEMETRY_HAVE_EXCEPTIONS 1 +# endif // defined(__EXCEPTIONS) && OPENTELEMETRY_HAVE_FEATURE(cxx_exceptions) +# elif OPENTELEMETRY_HAVE_FEATURE(cxx_exceptions) +# define OPENTELEMETRY_HAVE_EXCEPTIONS 1 +// Handle remaining special cases and default to exceptions being supported. +# elif !(defined(__GNUC__) && !defined(__EXCEPTIONS) && !defined(__cpp_exceptions)) && \ + !(defined(_MSC_VER) && !defined(_CPPUNWIND)) +# define OPENTELEMETRY_HAVE_EXCEPTIONS 1 +# endif +#endif +#ifndef OPENTELEMETRY_HAVE_EXCEPTIONS +# define OPENTELEMETRY_HAVE_EXCEPTIONS 0 +#endif + +/* + OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND indicates that a resource owned by a function + parameter or implicit object parameter is retained by the return value of the + annotated function (or, for a parameter of a constructor, in the value of the + constructed object). This attribute causes warnings to be produced if a + temporary object does not live long enough. + + When applied to a reference parameter, the referenced object is assumed to be + retained by the return value of the function. When applied to a non-reference + parameter (for example, a pointer or a class type), all temporaries + referenced by the parameter are assumed to be retained by the return value of + the function. + + See also the upstream documentation: + https://clang.llvm.org/docs/AttributeReference.html#lifetimebound +*/ +#ifndef OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND +# if OPENTELEMETRY_HAVE_CPP_ATTRIBUTE(clang::lifetimebound) +# define OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]] +# elif OPENTELEMETRY_HAVE_ATTRIBUTE(lifetimebound) +# define OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound)) +# else +# define OPENTELEMETRY_ATTRIBUTE_LIFETIME_BOUND +# endif +#endif + +// OPENTELEMETRY_HAVE_MEMORY_SANITIZER +// +// MemorySanitizer (MSan) is a detector of uninitialized reads. It consists of +// a compiler instrumentation module and a run-time library. +#ifndef OPENTELEMETRY_HAVE_MEMORY_SANITIZER +# if !defined(__native_client__) && OPENTELEMETRY_HAVE_FEATURE(memory_sanitizer) +# define OPENTELEMETRY_HAVE_MEMORY_SANITIZER 1 +# else +# define OPENTELEMETRY_HAVE_MEMORY_SANITIZER 0 +# endif +#endif + +#if OPENTELEMETRY_HAVE_MEMORY_SANITIZER && OPENTELEMETRY_HAVE_ATTRIBUTE(no_sanitize_memory) +# define OPENTELEMETRY_SANITIZER_NO_MEMORY \ + __attribute__((no_sanitize_memory)) // __attribute__((no_sanitize("memory"))) +#else +# define OPENTELEMETRY_SANITIZER_NO_MEMORY +#endif + +// OPENTELEMETRY_HAVE_THREAD_SANITIZER +// +// ThreadSanitizer (TSan) is a fast data race detector. +#ifndef OPENTELEMETRY_HAVE_THREAD_SANITIZER +# if defined(__SANITIZE_THREAD__) +# define OPENTELEMETRY_HAVE_THREAD_SANITIZER 1 +# elif OPENTELEMETRY_HAVE_FEATURE(thread_sanitizer) +# define OPENTELEMETRY_HAVE_THREAD_SANITIZER 1 +# else +# define OPENTELEMETRY_HAVE_THREAD_SANITIZER 0 +# endif +#endif + +#if OPENTELEMETRY_HAVE_THREAD_SANITIZER && OPENTELEMETRY_HAVE_ATTRIBUTE(no_sanitize_thread) +# define OPENTELEMETRY_SANITIZER_NO_THREAD \ + __attribute__((no_sanitize_thread)) // __attribute__((no_sanitize("thread"))) +#else +# define OPENTELEMETRY_SANITIZER_NO_THREAD +#endif + +// OPENTELEMETRY_HAVE_ADDRESS_SANITIZER +// +// AddressSanitizer (ASan) is a fast memory error detector. +#ifndef OPENTELEMETRY_HAVE_ADDRESS_SANITIZER +# if defined(__SANITIZE_ADDRESS__) +# define OPENTELEMETRY_HAVE_ADDRESS_SANITIZER 1 +# elif OPENTELEMETRY_HAVE_FEATURE(address_sanitizer) +# define OPENTELEMETRY_HAVE_ADDRESS_SANITIZER 1 +# else +# define OPENTELEMETRY_HAVE_ADDRESS_SANITIZER 0 +# endif +#endif + +// OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER +// +// Hardware-Assisted AddressSanitizer (or HWASAN) is even faster than asan +// memory error detector which can use CPU features like ARM TBI, Intel LAM or +// AMD UAI. +#ifndef OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER +# if defined(__SANITIZE_HWADDRESS__) +# define OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER 1 +# elif OPENTELEMETRY_HAVE_FEATURE(hwaddress_sanitizer) +# define OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER 1 +# else +# define OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER 0 +# endif +#endif + +#if OPENTELEMETRY_HAVE_ADDRESS_SANITIZER && OPENTELEMETRY_HAVE_ATTRIBUTE(no_sanitize_address) +# define OPENTELEMETRY_SANITIZER_NO_ADDRESS \ + __attribute__((no_sanitize_address)) // __attribute__((no_sanitize("address"))) +#elif OPENTELEMETRY_HAVE_ADDRESS_SANITIZER && defined(_MSC_VER) && _MSC_VER >= 1928 +# define OPENTELEMETRY_SANITIZER_NO_ADDRESS __declspec(no_sanitize_address) +#elif OPENTELEMETRY_HAVE_HWADDRESS_SANITIZER && OPENTELEMETRY_HAVE_ATTRIBUTE(no_sanitize) +# define OPENTELEMETRY_SANITIZER_NO_ADDRESS __attribute__((no_sanitize("hwaddress"))) +#else +# define OPENTELEMETRY_SANITIZER_NO_ADDRESS +#endif diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/spin_lock_mutex.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/spin_lock_mutex.h new file mode 100644 index 000000000..7031fa4d2 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/spin_lock_mutex.h @@ -0,0 +1,133 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include +#include + +#include "opentelemetry/version.h" + +#if defined(_MSC_VER) +# define _WINSOCKAPI_ // stops including winsock.h +# include +#elif defined(__i386__) || defined(__x86_64__) +# if defined(__clang__) +# include +# elif defined(__INTEL_COMPILER) +# include +# endif +#endif + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace common +{ + +constexpr int SPINLOCK_FAST_ITERATIONS = 100; +constexpr int SPINLOCK_SLEEP_MS = 1; + +/** + * A Mutex which uses atomic flags and spin-locks instead of halting threads. + * + * This mutex uses an incremental back-off strategy with the following phases: + * 1. A tight spin-lock loop (pending: using hardware PAUSE/YIELD instructions) + * 2. A loop where the current thread yields control after checking the lock. + * 3. Issuing a thread-sleep call before starting back in phase 1. + * + * This is meant to give a good balance of perofrmance and CPU consumption in + * practice. + * + * This mutex uses an incremental back-off strategy with the following phases: + * 1. A tight spin-lock loop (pending: using hardware PAUSE/YIELD instructions) + * 2. A loop where the current thread yields control after checking the lock. + * 3. Issuing a thread-sleep call before starting back in phase 1. + * + * This is meant to give a good balance of perofrmance and CPU consumption in + * practice. + * + * This class implements the `BasicLockable` specification: + * https://en.cppreference.com/w/cpp/named_req/BasicLockable + */ +class SpinLockMutex +{ +public: + SpinLockMutex() noexcept {} + ~SpinLockMutex() noexcept = default; + SpinLockMutex(const SpinLockMutex &) = delete; + SpinLockMutex &operator=(const SpinLockMutex &) = delete; + + static inline void fast_yield() noexcept + { +// Issue a Pause/Yield instruction while spinning. +#if defined(_MSC_VER) + YieldProcessor(); +#elif defined(__i386__) || defined(__x86_64__) +# if defined(__clang__) || defined(__INTEL_COMPILER) + _mm_pause(); +# else + __builtin_ia32_pause(); +# endif +#elif defined(__armel__) || defined(__ARMEL__) + asm volatile("nop" ::: "memory"); +#elif defined(__arm__) || defined(__aarch64__) // arm big endian / arm64 + __asm__ __volatile__("yield" ::: "memory"); +#else + // TODO: Issue PAGE/YIELD on other architectures. +#endif + } + + /** + * Attempts to lock the mutex. Return immediately with `true` (success) or `false` (failure). + */ + bool try_lock() noexcept + { + return !flag_.load(std::memory_order_relaxed) && + !flag_.exchange(true, std::memory_order_acquire); + } + + /** + * Blocks until a lock can be obtained for the current thread. + * + * This mutex will spin the current CPU waiting for the lock to be available. This can have + * decent performance in scenarios where there is low lock contention and lock-holders achieve + * their work quickly. It degrades in scenarios where locked tasks take a long time. + */ + void lock() noexcept + { + for (;;) + { + // Try once + if (!flag_.exchange(true, std::memory_order_acquire)) + { + return; + } + // Spin-Fast (goal ~10ns) + for (std::size_t i = 0; i < SPINLOCK_FAST_ITERATIONS; ++i) + { + if (try_lock()) + { + return; + } + fast_yield(); + } + // Yield then try again (goal ~100ns) + std::this_thread::yield(); + if (try_lock()) + { + return; + } + // Sleep and then start the whole process again. (goal ~1000ns) + std::this_thread::sleep_for(std::chrono::milliseconds(SPINLOCK_SLEEP_MS)); + } + return; + } + /** Releases the lock held by the execution agent. Throws no exceptions. */ + void unlock() noexcept { flag_.store(false, std::memory_order_release); } + +private: + std::atomic flag_{false}; +}; + +} // namespace common +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/string_util.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/string_util.h new file mode 100644 index 000000000..273a65272 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/string_util.h @@ -0,0 +1,42 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace common +{ + +class StringUtil +{ +public: + static nostd::string_view Trim(nostd::string_view str, size_t left, size_t right) noexcept + { + while (left <= right && isspace(str[left])) + { + left++; + } + while (left <= right && isspace(str[right])) + { + right--; + } + return str.substr(left, 1 + right - left); + } + + static nostd::string_view Trim(nostd::string_view str) noexcept + { + if (str.empty()) + { + return str; + } + + return Trim(str, 0, str.size() - 1); + } +}; + +} // namespace common + +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/timestamp.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/timestamp.h new file mode 100644 index 000000000..f7c79b8b5 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/common/timestamp.h @@ -0,0 +1,206 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include + +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace common +{ +/** + * @brief A timepoint relative to the system clock epoch. + * + * This is used for marking the beginning and end of an operation. + */ +class SystemTimestamp +{ +public: + /** + * @brief Initializes a system timestamp pointing to the start of the epoch. + */ + SystemTimestamp() noexcept : nanos_since_epoch_{0} {} + + /** + * @brief Initializes a system timestamp from a duration. + * + * @param time_since_epoch Time elapsed since the beginning of the epoch. + */ + template + explicit SystemTimestamp(const std::chrono::duration &time_since_epoch) noexcept + : nanos_since_epoch_{static_cast( + std::chrono::duration_cast(time_since_epoch).count())} + {} + + /** + * @brief Initializes a system timestamp based on a point in time. + * + * @param time_point A point in time. + */ + /*implicit*/ SystemTimestamp(const std::chrono::system_clock::time_point &time_point) noexcept + : SystemTimestamp{time_point.time_since_epoch()} + {} + + /** + * @brief Returns a time point for the time stamp. + * + * @return A time point corresponding to the time stamp. + */ + operator std::chrono::system_clock::time_point() const noexcept + { + return std::chrono::system_clock::time_point{ + std::chrono::duration_cast( + std::chrono::nanoseconds{nanos_since_epoch_})}; + } + + /** + * @brief Returns the nanoseconds since the beginning of the epoch. + * + * @return Elapsed nanoseconds since the beginning of the epoch for this timestamp. + */ + std::chrono::nanoseconds time_since_epoch() const noexcept + { + return std::chrono::nanoseconds{nanos_since_epoch_}; + } + + /** + * @brief Compare two steady time stamps. + * + * @return true if the two time stamps are equal. + */ + bool operator==(const SystemTimestamp &other) const noexcept + { + return nanos_since_epoch_ == other.nanos_since_epoch_; + } + + /** + * @brief Compare two steady time stamps for inequality. + * + * @return true if the two time stamps are not equal. + */ + bool operator!=(const SystemTimestamp &other) const noexcept + { + return nanos_since_epoch_ != other.nanos_since_epoch_; + } + +private: + int64_t nanos_since_epoch_; +}; + +/** + * @brief A timepoint relative to the monotonic clock epoch + * + * This is used for calculating the duration of an operation. + */ +class SteadyTimestamp +{ +public: + /** + * @brief Initializes a monotonic timestamp pointing to the start of the epoch. + */ + SteadyTimestamp() noexcept : nanos_since_epoch_{0} {} + + /** + * @brief Initializes a monotonic timestamp from a duration. + * + * @param time_since_epoch Time elapsed since the beginning of the epoch. + */ + template + explicit SteadyTimestamp(const std::chrono::duration &time_since_epoch) noexcept + : nanos_since_epoch_{static_cast( + std::chrono::duration_cast(time_since_epoch).count())} + {} + + /** + * @brief Initializes a monotonic timestamp based on a point in time. + * + * @param time_point A point in time. + */ + /*implicit*/ SteadyTimestamp(const std::chrono::steady_clock::time_point &time_point) noexcept + : SteadyTimestamp{time_point.time_since_epoch()} + {} + + /** + * @brief Returns a time point for the time stamp. + * + * @return A time point corresponding to the time stamp. + */ + operator std::chrono::steady_clock::time_point() const noexcept + { + return std::chrono::steady_clock::time_point{ + std::chrono::duration_cast( + std::chrono::nanoseconds{nanos_since_epoch_})}; + } + + /** + * @brief Returns the nanoseconds since the beginning of the epoch. + * + * @return Elapsed nanoseconds since the beginning of the epoch for this timestamp. + */ + std::chrono::nanoseconds time_since_epoch() const noexcept + { + return std::chrono::nanoseconds{nanos_since_epoch_}; + } + + /** + * @brief Compare two steady time stamps. + * + * @return true if the two time stamps are equal. + */ + bool operator==(const SteadyTimestamp &other) const noexcept + { + return nanos_since_epoch_ == other.nanos_since_epoch_; + } + + /** + * @brief Compare two steady time stamps for inequality. + * + * @return true if the two time stamps are not equal. + */ + bool operator!=(const SteadyTimestamp &other) const noexcept + { + return nanos_since_epoch_ != other.nanos_since_epoch_; + } + +private: + int64_t nanos_since_epoch_; +}; + +class DurationUtil +{ +public: + template + static std::chrono::duration AdjustWaitForTimeout( + std::chrono::duration timeout, + std::chrono::duration indefinite_value) noexcept + { + // Do not call now() when this duration is max value, now() may have a expensive cost. + if (timeout == (std::chrono::duration::max)()) + { + return indefinite_value; + } + + // std::future::wait_for, std::this_thread::sleep_for, and std::condition_variable::wait_for + // may use steady_clock or system_clock.We need make sure now() + timeout do not overflow. + auto max_timeout = std::chrono::duration_cast>( + (std::chrono::steady_clock::time_point::max)() - std::chrono::steady_clock::now()); + if (timeout >= max_timeout) + { + return indefinite_value; + } + max_timeout = std::chrono::duration_cast>( + (std::chrono::system_clock::time_point::max)() - std::chrono::system_clock::now()); + if (timeout >= max_timeout) + { + return indefinite_value; + } + + return timeout; + } +}; + +} // namespace common +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/config.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/config.h new file mode 100644 index 000000000..cb52f3b5d --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/config.h @@ -0,0 +1,19 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include // IWYU pragma: keep + +#if defined(OPENTELEMETRY_ABI_VERSION_NO) && OPENTELEMETRY_ABI_VERSION_NO >= 2 +# error \ + "opentelemetry/config.h is removed in ABI version 2 and later. Please use opentelemetry/version.h instead." +#else +# if defined(__clang__) || defined(__GNUC__) +# pragma GCC warning \ + "opentelemetry/config.h is deprecated. Please use opentelemetry/version.h instead." +# elif defined(_MSC_VER) +# pragma message( \ + "[WARNING]: opentelemetry/config.h is deprecated. Please use opentelemetry/version.h instead.") +# endif +#endif diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/context/context.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/context/context.h new file mode 100644 index 000000000..924036efa --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/context/context.h @@ -0,0 +1,171 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include + +#include "opentelemetry/context/context_value.h" +#include "opentelemetry/nostd/shared_ptr.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/nostd/variant.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace context +{ + +// The context class provides a context identifier. Is built as a linked list +// of DataList nodes and each context holds a shared_ptr to a place within +// the list that determines which keys and values it has access to. All that +// come before and none that come after. +class Context +{ + +public: + Context() = default; + // Creates a context object from a map of keys and identifiers, this will + // hold a shared_ptr to the head of the DataList linked list + template + Context(const T &keys_and_values) noexcept + : head_{nostd::shared_ptr{new DataList(keys_and_values)}} + {} + + // Creates a context object from a key and value, this will + // hold a shared_ptr to the head of the DataList linked list + Context(nostd::string_view key, ContextValue value) noexcept + : head_{nostd::shared_ptr{new DataList(key, value)}} + {} + + // Accepts a new iterable and then returns a new context that + // contains the new key and value data. It attaches the + // exisiting list to the end of the new list. + template + Context SetValues(T &values) noexcept + { + Context context = Context(values); + nostd::shared_ptr last = context.head_; + while (last->next_ != nullptr) + { + last = last->next_; + } + last->next_ = head_; + return context; + } + + // Accepts a new iterable and then returns a new context that + // contains the new key and value data. It attaches the + // exisiting list to the end of the new list. + Context SetValue(nostd::string_view key, ContextValue value) noexcept + { + Context context = Context(key, value); + context.head_->next_ = head_; + return context; + } + + // Returns the value associated with the passed in key. + context::ContextValue GetValue(const nostd::string_view key) const noexcept + { + for (DataList *data = head_.get(); data != nullptr; data = data->next_.get()) + { + if (key.size() == data->key_length_) + { + if (std::memcmp(key.data(), data->key_, data->key_length_) == 0) + { + return data->value_; + } + } + } + return ContextValue{}; + } + + // Checks for key and returns true if found + bool HasKey(const nostd::string_view key) const noexcept + { + return !nostd::holds_alternative(GetValue(key)); + } + + bool operator==(const Context &other) const noexcept { return (head_ == other.head_); } + +private: + // A linked list to contain the keys and values of this context node + struct DataList + { + char *key_ = nullptr; + + nostd::shared_ptr next_{nullptr}; + + size_t key_length_ = 0UL; + + ContextValue value_; + + DataList() = default; + + // Builds a data list off of a key and value iterable and returns the head + template + DataList(const T &keys_and_vals) + { + bool first = true; + auto *node = this; + for (auto &iter : keys_and_vals) + { + if (first) + { + *node = DataList(iter.first, iter.second); + first = false; + } + else + { + node->next_ = nostd::shared_ptr(new DataList(iter.first, iter.second)); + node = node->next_.get(); + } + } + } + + // Builds a data list with just a key and value, so it will just be the head + // and returns that head. + DataList(nostd::string_view key, const ContextValue &value) + { + key_ = new char[key.size()]; + key_length_ = key.size(); + std::memcpy(key_, key.data(), key.size() * sizeof(char)); + next_ = nostd::shared_ptr{nullptr}; + value_ = value; + } + + DataList(const DataList &other) + : key_(new char[other.key_length_]), + next_(other.next_), + key_length_(other.key_length_), + value_(other.value_) + { + std::memcpy(key_, other.key_, other.key_length_ * sizeof(char)); + } + + DataList &operator=(DataList &&other) noexcept + { + key_length_ = other.key_length_; + value_ = std::move(other.value_); + next_ = std::move(other.next_); + + key_ = other.key_; + other.key_ = nullptr; + + return *this; + } + + ~DataList() + { + if (key_ != nullptr) + { + delete[] key_; + } + } + }; + + // Head of the list which holds the keys and values of this context + nostd::shared_ptr head_; +}; +} // namespace context +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/context/context_value.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/context/context_value.h new file mode 100644 index 000000000..27bd40fb0 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/context/context_value.h @@ -0,0 +1,35 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +#include "opentelemetry/nostd/shared_ptr.h" +#include "opentelemetry/nostd/variant.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace baggage +{ +class Baggage; +} // namespace baggage + +namespace trace +{ +class Span; +class SpanContext; +} // namespace trace + +namespace context +{ +using ContextValue = nostd::variant, + nostd::shared_ptr, + nostd::shared_ptr>; +} // namespace context +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/context/propagation/composite_propagator.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/context/propagation/composite_propagator.h new file mode 100644 index 000000000..f7afe23bf --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/context/propagation/composite_propagator.h @@ -0,0 +1,93 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include + +#include "opentelemetry/context/propagation/text_map_propagator.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace context +{ +namespace propagation +{ + +class CompositePropagator : public TextMapPropagator +{ +public: + CompositePropagator(std::vector> propagators) + : propagators_(std::move(propagators)) + {} + + /** + * Run each of the configured propagators with the given context and carrier. + * Propagators are run in the order they are configured, so if multiple + * propagators write the same carrier key, the propagator later in the list + * will "win". + * + * @param carrier Carrier into which context will be injected + * @param context Context to inject + * + */ + + void Inject(TextMapCarrier &carrier, const context::Context &context) noexcept override + { + for (auto &p : propagators_) + { + p->Inject(carrier, context); + } + } + + /** + * Run each of the configured propagators with the given context and carrier. + * Propagators are run in the order they are configured, so if multiple + * propagators write the same context key, the propagator later in the list + * will "win". + * + * @param carrier Carrier from which to extract context + * @param context Context to add values to + */ + context::Context Extract(const TextMapCarrier &carrier, + context::Context &context) noexcept override + { + auto first = true; + context::Context tmp_context; + for (auto &p : propagators_) + { + if (first) + { + tmp_context = p->Extract(carrier, context); + first = false; + } + else + { + tmp_context = p->Extract(carrier, tmp_context); + } + } + return propagators_.size() ? tmp_context : context; + } + + /** + * Invoke callback with fields set to carrier by `inject` method for all the + * configured propagators + * Returns true if all invocation return true + */ + bool Fields(nostd::function_ref callback) const noexcept override + { + bool status = true; + for (auto &p : propagators_) + { + status = status && p->Fields(callback); + } + return status; + } + +private: + std::vector> propagators_; +}; +} // namespace propagation +} // namespace context +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/context/propagation/global_propagator.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/context/propagation/global_propagator.h new file mode 100644 index 000000000..85293202f --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/context/propagation/global_propagator.h @@ -0,0 +1,57 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +#include "opentelemetry/context/propagation/noop_propagator.h" + +#include "opentelemetry/common/macros.h" +#include "opentelemetry/common/spin_lock_mutex.h" +#include "opentelemetry/nostd/shared_ptr.h" + +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace context +{ +namespace propagation +{ + +class TextMapPropagator; + +/* Stores the singleton TextMapPropagator */ + +class OPENTELEMETRY_EXPORT GlobalTextMapPropagator +{ +public: + static nostd::shared_ptr GetGlobalPropagator() noexcept + { + std::lock_guard guard(GetLock()); + return nostd::shared_ptr(GetPropagator()); + } + + static void SetGlobalPropagator(const nostd::shared_ptr &prop) noexcept + { + std::lock_guard guard(GetLock()); + GetPropagator() = prop; + } + +private: + OPENTELEMETRY_API_SINGLETON static nostd::shared_ptr &GetPropagator() noexcept + { + static nostd::shared_ptr propagator(new NoOpPropagator()); + return propagator; + } + + OPENTELEMETRY_API_SINGLETON static common::SpinLockMutex &GetLock() noexcept + { + static common::SpinLockMutex lock; + return lock; + } +}; + +} // namespace propagation +} // namespace context +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/context/propagation/noop_propagator.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/context/propagation/noop_propagator.h new file mode 100644 index 000000000..4e1b30c17 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/context/propagation/noop_propagator.h @@ -0,0 +1,40 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/context/propagation/text_map_propagator.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace context +{ +namespace propagation +{ + +/** + * No-op implementation TextMapPropagator + */ +class NoOpPropagator : public TextMapPropagator +{ +public: + /** Noop extract function does nothing and returns the input context */ + context::Context Extract(const TextMapCarrier & /*carrier*/, + context::Context &context) noexcept override + { + return context; + } + + /** Noop inject function does nothing */ + void Inject(TextMapCarrier & /*carrier*/, + const context::Context & /* context */) noexcept override + {} + + bool Fields(nostd::function_ref /* callback */) const noexcept override + { + return true; + } +}; +} // namespace propagation +} // namespace context +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/context/propagation/text_map_propagator.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/context/propagation/text_map_propagator.h new file mode 100644 index 000000000..21bc29361 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/context/propagation/text_map_propagator.h @@ -0,0 +1,59 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/context/context.h" +#include "opentelemetry/nostd/function_ref.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace context +{ +namespace propagation +{ + +// TextMapCarrier is the storage medium used by TextMapPropagator. +class TextMapCarrier +{ +public: + // returns the value associated with the passed key. + virtual nostd::string_view Get(nostd::string_view key) const noexcept = 0; + + // stores the key-value pair. + virtual void Set(nostd::string_view key, nostd::string_view value) noexcept = 0; + + /* list of all the keys in the carrier. + By default, it returns true without invoking callback */ + virtual bool Keys(nostd::function_ref /* callback */) const noexcept + { + return true; + } + virtual ~TextMapCarrier() = default; +}; + +// The TextMapPropagator class provides an interface that enables extracting and injecting +// context into carriers that travel in-band across process boundaries. HTTP frameworks and clients +// can integrate with TextMapPropagator by providing the object containing the +// headers, and a getter and setter function for the extraction and +// injection of values, respectively. + +class TextMapPropagator +{ +public: + // Returns the context that is stored in the carrier with the TextMapCarrier as extractor. + virtual context::Context Extract(const TextMapCarrier &carrier, + context::Context &context) noexcept = 0; + + // Sets the context for carrier with self defined rules. + virtual void Inject(TextMapCarrier &carrier, const context::Context &context) noexcept = 0; + + // Gets the fields set in the carrier by the `inject` method + virtual bool Fields(nostd::function_ref callback) const noexcept = 0; + + virtual ~TextMapPropagator() = default; +}; +} // namespace propagation +} // namespace context +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/context/runtime_context.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/context/runtime_context.h new file mode 100644 index 000000000..e3f88254c --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/context/runtime_context.h @@ -0,0 +1,340 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include + +#include "opentelemetry/common/macros.h" +#include "opentelemetry/context/context.h" +#include "opentelemetry/context/context_value.h" +#include "opentelemetry/nostd/shared_ptr.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/nostd/unique_ptr.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace context +{ +// The Token object provides is returned when attaching objects to the +// RuntimeContext object and is associated with a context object, and +// can be provided to the RuntimeContext Detach method to remove the +// associated context from the RuntimeContext. +class Token +{ +public: + bool operator==(const Context &other) const noexcept { return context_ == other; } + + ~Token() noexcept; + +private: + friend class RuntimeContextStorage; + + // A constructor that sets the token's Context object to the + // one that was passed in. + Token(const Context &context) : context_(context) {} + + const Context context_; +}; + +/** + * RuntimeContextStorage is used by RuntimeContext to store Context frames. + * + * Custom context management strategies can be implemented by deriving from + * this class and passing an initialized RuntimeContextStorage object to + * RuntimeContext::SetRuntimeContextStorage. + */ +class OPENTELEMETRY_EXPORT RuntimeContextStorage +{ +public: + /** + * Return the current context. + * @return the current context + */ + virtual Context GetCurrent() noexcept = 0; + + /** + * Set the current context. + * @param the new current context + * @return a token for the new current context. This never returns a nullptr. + */ + virtual nostd::unique_ptr Attach(const Context &context) noexcept = 0; + + /** + * Detach the context related to the given token. + * @param token a token related to a context + * @return true if the context could be detached + */ + virtual bool Detach(Token &token) noexcept = 0; + + virtual ~RuntimeContextStorage() {} + +protected: + nostd::unique_ptr CreateToken(const Context &context) noexcept + { + return nostd::unique_ptr(new Token(context)); + } +}; + +/** + * Construct and return the default RuntimeContextStorage + * @return a ThreadLocalContextStorage + */ +static RuntimeContextStorage *GetDefaultStorage() noexcept; + +// Provides a wrapper for propagating the context object globally. +// +// By default, a thread-local runtime context storage is used. +class OPENTELEMETRY_EXPORT RuntimeContext +{ +public: + // Return the current context. + static Context GetCurrent() noexcept { return GetRuntimeContextStorage()->GetCurrent(); } + + // Sets the current 'Context' object. Returns a token + // that can be used to reset to the previous Context. + static nostd::unique_ptr Attach(const Context &context) noexcept + { + return GetRuntimeContextStorage()->Attach(context); + } + + // Resets the context to a previous value stored in the + // passed in token. Returns true if successful, false otherwise + static bool Detach(Token &token) noexcept { return GetRuntimeContextStorage()->Detach(token); } + + // Sets the Key and Value into the passed in context or if a context is not + // passed in, the RuntimeContext. + // Should be used to SetValues to the current RuntimeContext, is essentially + // equivalent to RuntimeContext::GetCurrent().SetValue(key,value). Keep in + // mind that the current RuntimeContext will not be changed, and the new + // context will be returned. + static Context SetValue(nostd::string_view key, + const ContextValue &value, + Context *context = nullptr) noexcept + { + Context temp_context; + if (context == nullptr) + { + temp_context = GetCurrent(); + } + else + { + temp_context = *context; + } + return temp_context.SetValue(key, value); + } + + // Returns the value associated with the passed in key and either the + // passed in context* or the runtime context if a context is not passed in. + // Should be used to get values from the current RuntimeContext, is + // essentially equivalent to RuntimeContext::GetCurrent().GetValue(key). + static ContextValue GetValue(nostd::string_view key, Context *context = nullptr) noexcept + { + Context temp_context; + if (context == nullptr) + { + temp_context = GetCurrent(); + } + else + { + temp_context = *context; + } + return temp_context.GetValue(key); + } + + /** + * Provide a custom runtime context storage. + * + * This provides a possibility to override the default thread-local runtime + * context storage. This has to be set before any spans are created by the + * application, otherwise the behavior is undefined. + * + * @param storage a custom runtime context storage + */ + static void SetRuntimeContextStorage( + const nostd::shared_ptr &storage) noexcept + { + GetStorage() = storage; + } + + /** + * Provide a pointer to const runtime context storage. + * + * The returned pointer can only be used for extending the lifetime of the runtime context + * storage. + * + */ + static nostd::shared_ptr GetConstRuntimeContextStorage() noexcept + { + return GetRuntimeContextStorage(); + } + +private: + static nostd::shared_ptr GetRuntimeContextStorage() noexcept + { + return GetStorage(); + } + + OPENTELEMETRY_API_SINGLETON static nostd::shared_ptr &GetStorage() noexcept + { + static nostd::shared_ptr context(GetDefaultStorage()); + return context; + } +}; + +inline Token::~Token() noexcept +{ + context::RuntimeContext::Detach(*this); +} + +// The ThreadLocalContextStorage class is a derived class from +// RuntimeContextStorage and provides a wrapper for propagating context through +// cpp thread locally. This file must be included to use the RuntimeContext +// class if another implementation has not been registered. +class ThreadLocalContextStorage : public RuntimeContextStorage +{ +public: + ThreadLocalContextStorage() noexcept = default; + + // Return the current context. + Context GetCurrent() noexcept override { return GetStack().Top(); } + + // Resets the context to the value previous to the passed in token. This will + // also detach all child contexts of the passed in token. + // Returns true if successful, false otherwise. + bool Detach(Token &token) noexcept override + { + // In most cases, the context to be detached is on the top of the stack. + if (token == GetStack().Top()) + { + GetStack().Pop(); + return true; + } + + if (!GetStack().Contains(token)) + { + return false; + } + + while (!(token == GetStack().Top())) + { + GetStack().Pop(); + } + + GetStack().Pop(); + + return true; + } + + // Sets the current 'Context' object. Returns a token + // that can be used to reset to the previous Context. + nostd::unique_ptr Attach(const Context &context) noexcept override + { + GetStack().Push(context); + return CreateToken(context); + } + +private: + // A nested class to store the attached contexts in a stack. + class Stack + { + friend class ThreadLocalContextStorage; + + Stack() noexcept : size_(0), capacity_(0), base_(nullptr) {} + + // Pops the top Context off the stack. + void Pop() noexcept + { + if (size_ == 0) + { + return; + } + // Store empty Context before decrementing `size`, to ensure + // the shared_ptr object (if stored in prev context object ) are released. + // The stack is not resized, and the unused memory would be reutilised + // for subsequent context storage. + base_[size_ - 1] = Context(); + size_ -= 1; + } + + bool Contains(const Token &token) const noexcept + { + for (size_t pos = size_; pos > 0; --pos) + { + if (token == base_[pos - 1]) + { + return true; + } + } + + return false; + } + + // Returns the Context at the top of the stack. + Context Top() const noexcept + { + if (size_ == 0) + { + return Context(); + } + return base_[size_ - 1]; + } + + // Pushes the passed in context pointer to the top of the stack + // and resizes if necessary. + void Push(const Context &context) noexcept + { + size_++; + if (size_ > capacity_) + { + Resize(size_ * 2); + } + base_[size_ - 1] = context; + } + + // Reallocates the storage array to the pass in new capacity size. + void Resize(size_t new_capacity) noexcept + { + size_t old_size = size_ - 1; + if (new_capacity == 0) + { + new_capacity = 2; + } + Context *temp = new Context[new_capacity]; + if (base_ != nullptr) + { + // vs2015 does not like this construct considering it unsafe: + // - std::copy(base_, base_ + old_size, temp); + // Ref. + // https://stackoverflow.com/questions/12270224/xutility2227-warning-c4996-std-copy-impl + for (size_t i = 0; i < (std::min)(old_size, new_capacity); i++) + { + temp[i] = base_[i]; + } + delete[] base_; + } + base_ = temp; + capacity_ = new_capacity; + } + + ~Stack() noexcept { delete[] base_; } + + size_t size_; + size_t capacity_; + Context *base_; + }; + + OPENTELEMETRY_API_SINGLETON Stack &GetStack() + { + static thread_local Stack stack_ = Stack(); + return stack_; + } +}; + +static RuntimeContextStorage *GetDefaultStorage() noexcept +{ + return new ThreadLocalContextStorage(); +} +} // namespace context +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/detail/preprocessor.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/detail/preprocessor.h new file mode 100644 index 000000000..acdf02eb0 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/detail/preprocessor.h @@ -0,0 +1,25 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// NOTE - code within detail namespace implements internal details, and not part +// of the public interface. + +#pragma once + +#define OPENTELEMETRY_STRINGIFY(S) OPENTELEMETRY_STRINGIFY_(S) +#define OPENTELEMETRY_STRINGIFY_(S) #S + +#define OPENTELEMETRY_CONCAT(A, B) OPENTELEMETRY_CONCAT_(A, B) +#define OPENTELEMETRY_CONCAT_(A, B) A##B + +// Import the C++20 feature-test macros +#ifdef __has_include +# if __has_include() +# include +# endif +#elif defined(_MSC_VER) && ((defined(__cplusplus) && __cplusplus >= 202002L) || \ + (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)) +# if _MSC_VER >= 1922 +# include +# endif +#endif diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/event_id.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/event_id.h new file mode 100644 index 000000000..65306ef79 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/event_id.h @@ -0,0 +1,37 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/nostd/unique_ptr.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace logs +{ + +/** + * EventId class which acts the Id of the event with an optional name. + */ +class EventId +{ +public: + EventId(int64_t id, nostd::string_view name) noexcept + : id_{id}, name_{nostd::unique_ptr{new char[name.length() + 1]}} + { + std::copy(name.begin(), name.end(), name_.get()); + name_.get()[name.length()] = 0; + } + + EventId(int64_t id) noexcept : id_{id}, name_{nullptr} {} + +public: + int64_t id_; + nostd::unique_ptr name_; +}; + +} // namespace logs +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/event_logger.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/event_logger.h new file mode 100644 index 000000000..bcc103562 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/event_logger.h @@ -0,0 +1,82 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/logs/log_record.h" +#include "opentelemetry/logs/logger.h" +#include "opentelemetry/logs/logger_type_traits.h" +#include "opentelemetry/nostd/shared_ptr.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/nostd/unique_ptr.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace logs +{ +#if OPENTELEMETRY_ABI_VERSION_NO < 2 +/** + * Handles event log record creation. + **/ +class OPENTELEMETRY_DEPRECATED EventLogger +{ +public: + virtual ~EventLogger() = default; + + /* Returns the name of the logger */ + virtual const nostd::string_view GetName() noexcept = 0; + + /* Returns the delegate logger of this event logger */ + virtual nostd::shared_ptr GetDelegateLogger() noexcept = 0; + + /** + * Emit a event Log Record object + * + * @param event_name Event name + * @param log_record Log record + */ + virtual void EmitEvent(nostd::string_view event_name, + nostd::unique_ptr &&log_record) noexcept = 0; + + /** + * Emit a event Log Record object with arguments + * + * @param event_name Event name + * @tparam args Arguments which can be used to set data of log record by type. + * Severity -> severity, severity_text + * string_view -> body + * AttributeValue -> body + * SpanContext -> span_id,tace_id and trace_flags + * SpanId -> span_id + * TraceId -> tace_id + * TraceFlags -> trace_flags + * SystemTimestamp -> timestamp + * system_clock::time_point -> timestamp + * KeyValueIterable -> attributes + * Key value iterable container -> attributes + * span> -> attributes(return type of MakeAttributes) + */ + template + void EmitEvent(nostd::string_view event_name, ArgumentType &&...args) + { + nostd::shared_ptr delegate_logger = GetDelegateLogger(); + if (!delegate_logger) + { + return; + } + nostd::unique_ptr log_record = delegate_logger->CreateLogRecord(); + + IgnoreTraitResult(detail::LogRecordSetterTrait::type>::Set( + log_record.get(), std::forward(args))...); + + EmitEvent(event_name, std::move(log_record)); + } + +private: + template + void IgnoreTraitResult(ValueType &&...) + {} +}; +#endif +} // namespace logs +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/event_logger_provider.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/event_logger_provider.h new file mode 100644 index 000000000..9eea0ca23 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/event_logger_provider.h @@ -0,0 +1,37 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/nostd/shared_ptr.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace logs +{ + +class EventLogger; +class Logger; + +#if OPENTELEMETRY_ABI_VERSION_NO < 2 +/** + * Creates new EventLogger instances. + */ +class OPENTELEMETRY_DEPRECATED EventLoggerProvider +{ +public: + virtual ~EventLoggerProvider() = default; + + /** + * Creates a named EventLogger instance. + * + */ + + virtual nostd::shared_ptr CreateEventLogger( + nostd::shared_ptr delegate_logger, + nostd::string_view event_domain) noexcept = 0; +}; +#endif +} // namespace logs +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/log_record.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/log_record.h new file mode 100644 index 000000000..81dec568e --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/log_record.h @@ -0,0 +1,92 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/common/attribute_value.h" +#include "opentelemetry/common/timestamp.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace trace +{ +class SpanId; +class TraceId; +class TraceFlags; +} // namespace trace + +namespace logs +{ + +enum class Severity : uint8_t; + +/** + * Maintains a representation of a log in a format that can be processed by a recorder. + * + * This class is thread-compatible. + */ +class LogRecord +{ +public: + virtual ~LogRecord() = default; + + /** + * Set the timestamp for this log. + * @param timestamp the timestamp to set + */ + virtual void SetTimestamp(common::SystemTimestamp timestamp) noexcept = 0; + + /** + * Set the observed timestamp for this log. + * @param timestamp the timestamp to set + */ + virtual void SetObservedTimestamp(common::SystemTimestamp timestamp) noexcept = 0; + + /** + * Set the severity for this log. + * @param severity the severity of the event + */ + virtual void SetSeverity(logs::Severity severity) noexcept = 0; + + /** + * Set body field for this log. + * @param message the body to set + */ + virtual void SetBody(const common::AttributeValue &message) noexcept = 0; + + /** + * Set an attribute of a log. + * @param key the name of the attribute + * @param value the attribute value + */ + virtual void SetAttribute(nostd::string_view key, + const common::AttributeValue &value) noexcept = 0; + + /** + * Set the Event Id. + * @param id The event id to set + * @param name Optional event name to set + */ + // TODO: mark this as pure virtual once all exporters have been updated + virtual void SetEventId(int64_t id, nostd::string_view name = {}) noexcept = 0; + + /** + * Set the trace id for this log. + * @param trace_id the trace id to set + */ + virtual void SetTraceId(const trace::TraceId &trace_id) noexcept = 0; + + /** + * Set the span id for this log. + * @param span_id the span id to set + */ + virtual void SetSpanId(const trace::SpanId &span_id) noexcept = 0; + + /** + * Inject trace_flags for this log. + * @param trace_flags the trace flags to set + */ + virtual void SetTraceFlags(const trace::TraceFlags &trace_flags) noexcept = 0; +}; +} // namespace logs +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/logger.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/logger.h new file mode 100644 index 000000000..52f403b0a --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/logger.h @@ -0,0 +1,492 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/logs/logger_type_traits.h" +#include "opentelemetry/logs/severity.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/nostd/unique_ptr.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace common +{ +class KeyValueIterable; +} // namespace common + +namespace logs +{ + +class EventId; +class LogRecord; + +/** + * Handles log record creation. + **/ +class Logger +{ +public: + virtual ~Logger() = default; + + /* Returns the name of the logger */ + virtual const nostd::string_view GetName() noexcept = 0; + + /** + * Create a Log Record object + * + * @return nostd::unique_ptr + */ + virtual nostd::unique_ptr CreateLogRecord() noexcept = 0; + + /** + * Emit a Log Record object + * + * @param log_record Log record + */ + virtual void EmitLogRecord(nostd::unique_ptr &&log_record) noexcept = 0; + + /** + * Emit a Log Record object with arguments + * + * @param log_record Log record + * @param args Arguments which can be used to set data of log record by type. + * Severity -> severity, severity_text + * string_view -> body + * AttributeValue -> body + * SpanContext -> span_id,trace_id and trace_flags + * SpanId -> span_id + * TraceId -> trace_id + * TraceFlags -> trace_flags + * SystemTimestamp -> timestamp + * system_clock::time_point -> timestamp + * KeyValueIterable -> attributes + * Key value iterable container -> attributes + * span> -> attributes(return type of MakeAttributes) + */ + template + void EmitLogRecord(nostd::unique_ptr &&log_record, ArgumentType &&...args) + { + if (!log_record) + { + return; + } + + // + // Keep the parameter pack unpacking order from left to right because left + // ones are usually more important like severity and event_id than the + // attributes. The left to right unpack order could pass the more important + // data to processors to avoid caching and memory allocating. + // +#if __cplusplus <= 201402L + // C++14 does not support fold expressions for parameter pack expansion. + int dummy[] = {(detail::LogRecordSetterTrait::type>::Set( + log_record.get(), std::forward(args)), + 0)...}; + IgnoreTraitResult(dummy); +#else + IgnoreTraitResult((detail::LogRecordSetterTrait::type>::Set( + log_record.get(), std::forward(args)), + ...)); +#endif + + EmitLogRecord(std::move(log_record)); + } + + /** + * Emit a Log Record object with arguments + * + * @param args Arguments which can be used to set data of log record by type. + * Severity -> severity, severity_text + * string_view -> body + * AttributeValue -> body + * SpanContext -> span_id,trace_id and trace_flags + * SpanId -> span_id + * TraceId -> trace_id + * TraceFlags -> trace_flags + * SystemTimestamp -> timestamp + * system_clock::time_point -> timestamp + * KeyValueIterable -> attributes + * Key value iterable container -> attributes + * span> -> attributes(return type of MakeAttributes) + */ + template + void EmitLogRecord(ArgumentType &&...args) + { + nostd::unique_ptr log_record = CreateLogRecord(); + + EmitLogRecord(std::move(log_record), std::forward(args)...); + } + + /** + * Writes a log with a severity of trace. + * @param args Arguments which can be used to set data of log record by type. + * string_view -> body + * AttributeValue -> body + * SpanContext -> span_id,trace_id and trace_flags + * SpanId -> span_id + * TraceId -> trace_id + * TraceFlags -> trace_flags + * SystemTimestamp -> timestamp + * system_clock::time_point -> timestamp + * KeyValueIterable -> attributes + * Key value iterable container -> attributes + * span> -> attributes(return type of MakeAttributes) + */ + template + void Trace(ArgumentType &&...args) noexcept + { + static_assert( + !detail::LogRecordHasType::type...>::value, + "Severity is already set."); + this->EmitLogRecord(Severity::kTrace, std::forward(args)...); + } + + /** + * Writes a log with a severity of debug. + * @param args Arguments which can be used to set data of log record by type. + * string_view -> body + * AttributeValue -> body + * SpanContext -> span_id,trace_id and trace_flags + * SpanId -> span_id + * TraceId -> trace_id + * TraceFlags -> trace_flags + * SystemTimestamp -> timestamp + * system_clock::time_point -> timestamp + * KeyValueIterable -> attributes + * Key value iterable container -> attributes + * span> -> attributes(return type of MakeAttributes) + */ + template + void Debug(ArgumentType &&...args) noexcept + { + static_assert( + !detail::LogRecordHasType::type...>::value, + "Severity is already set."); + this->EmitLogRecord(Severity::kDebug, std::forward(args)...); + } + + /** + * Writes a log with a severity of info. + * @param args Arguments which can be used to set data of log record by type. + * string_view -> body + * AttributeValue -> body + * SpanContext -> span_id,trace_id and trace_flags + * SpanId -> span_id + * TraceId -> trace_id + * TraceFlags -> trace_flags + * SystemTimestamp -> timestamp + * system_clock::time_point -> timestamp + * KeyValueIterable -> attributes + * Key value iterable container -> attributes + * span> -> attributes(return type of MakeAttributes) + */ + template + void Info(ArgumentType &&...args) noexcept + { + static_assert( + !detail::LogRecordHasType::type...>::value, + "Severity is already set."); + this->EmitLogRecord(Severity::kInfo, std::forward(args)...); + } + + /** + * Writes a log with a severity of warn. + * @param args Arguments which can be used to set data of log record by type. + * string_view -> body + * AttributeValue -> body + * SpanContext -> span_id,trace_id and trace_flags + * SpanId -> span_id + * TraceId -> trace_id + * TraceFlags -> trace_flags + * SystemTimestamp -> timestamp + * system_clock::time_point -> timestamp + * KeyValueIterable -> attributes + * Key value iterable container -> attributes + * span> -> attributes(return type of MakeAttributes) + */ + template + void Warn(ArgumentType &&...args) noexcept + { + static_assert( + !detail::LogRecordHasType::type...>::value, + "Severity is already set."); + this->EmitLogRecord(Severity::kWarn, std::forward(args)...); + } + + /** + * Writes a log with a severity of error. + * @param args Arguments which can be used to set data of log record by type. + * string_view -> body + * AttributeValue -> body + * SpanContext -> span_id,trace_id and trace_flags + * SpanId -> span_id + * TraceId -> trace_id + * TraceFlags -> trace_flags + * SystemTimestamp -> timestamp + * system_clock::time_point -> timestamp + * KeyValueIterable -> attributes + * Key value iterable container -> attributes + * span> -> attributes(return type of MakeAttributes) + */ + template + void Error(ArgumentType &&...args) noexcept + { + static_assert( + !detail::LogRecordHasType::type...>::value, + "Severity is already set."); + this->EmitLogRecord(Severity::kError, std::forward(args)...); + } + + /** + * Writes a log with a severity of fatal. + * @param args Arguments which can be used to set data of log record by type. + * string_view -> body + * AttributeValue -> body + * SpanContext -> span_id,trace_id and trace_flags + * SpanId -> span_id + * TraceId -> trace_id + * TraceFlags -> trace_flags + * SystemTimestamp -> timestamp + * system_clock::time_point -> timestamp + * KeyValueIterable -> attributes + * Key value iterable container -> attributes + * span> -> attributes(return type of MakeAttributes) + */ + template + void Fatal(ArgumentType &&...args) noexcept + { + static_assert( + !detail::LogRecordHasType::type...>::value, + "Severity is already set."); + this->EmitLogRecord(Severity::kFatal, std::forward(args)...); + } + + // + // OpenTelemetry C++ user-facing Logs API + // + + inline bool Enabled(Severity severity, const EventId &event_id) const noexcept + { + if OPENTELEMETRY_LIKELY_CONDITION (!Enabled(severity)) + { + return false; + } + return EnabledImplementation(severity, event_id); + } + + inline bool Enabled(Severity severity, int64_t event_id) const noexcept + { + if OPENTELEMETRY_LIKELY_CONDITION (!Enabled(severity)) + { + return false; + } + return EnabledImplementation(severity, event_id); + } + + inline bool Enabled(Severity severity) const noexcept + { + return static_cast(severity) >= OPENTELEMETRY_ATOMIC_READ_8(&minimum_severity_); + } + + /** + * Log an event + * + * @severity severity of the log + * @event_id event identifier of the log + * @format an utf-8 string following https://messagetemplates.org/ + * @attributes key value pairs of the log + */ + virtual void Log(Severity severity, + const EventId &event_id, + nostd::string_view format, + const common::KeyValueIterable &attributes) noexcept + { + this->EmitLogRecord(severity, event_id, format, attributes); + } + + virtual void Log(Severity severity, + int64_t event_id, + nostd::string_view format, + const common::KeyValueIterable &attributes) noexcept + { + this->EmitLogRecord(severity, EventId{event_id}, format, attributes); + } + + virtual void Log(Severity severity, + nostd::string_view format, + const common::KeyValueIterable &attributes) noexcept + { + this->EmitLogRecord(severity, format, attributes); + } + + virtual void Log(Severity severity, nostd::string_view message) noexcept + { + this->EmitLogRecord(severity, message); + } + + // Convenient wrappers based on virtual methods Log(). + // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#field-severitynumber + + inline void Trace(const EventId &event_id, + nostd::string_view format, + const common::KeyValueIterable &attributes) noexcept + { + this->Log(Severity::kTrace, event_id, format, attributes); + } + + inline void Trace(int64_t event_id, + nostd::string_view format, + const common::KeyValueIterable &attributes) noexcept + { + this->Log(Severity::kTrace, EventId{event_id}, format, attributes); + } + + inline void Trace(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept + { + this->Log(Severity::kTrace, format, attributes); + } + + inline void Trace(nostd::string_view message) noexcept { this->Log(Severity::kTrace, message); } + + inline void Debug(const EventId &event_id, + nostd::string_view format, + const common::KeyValueIterable &attributes) noexcept + { + this->Log(Severity::kDebug, event_id, format, attributes); + } + + inline void Debug(int64_t event_id, + nostd::string_view format, + const common::KeyValueIterable &attributes) noexcept + { + this->Log(Severity::kDebug, EventId{event_id}, format, attributes); + } + + inline void Debug(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept + { + this->Log(Severity::kDebug, format, attributes); + } + + inline void Debug(nostd::string_view message) noexcept { this->Log(Severity::kDebug, message); } + + inline void Info(const EventId &event_id, + nostd::string_view format, + const common::KeyValueIterable &attributes) noexcept + { + this->Log(Severity::kInfo, event_id, format, attributes); + } + + inline void Info(int64_t event_id, + nostd::string_view format, + const common::KeyValueIterable &attributes) noexcept + { + this->Log(Severity::kInfo, EventId{event_id}, format, attributes); + } + + inline void Info(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept + { + this->Log(Severity::kInfo, format, attributes); + } + + inline void Info(nostd::string_view message) noexcept { this->Log(Severity::kInfo, message); } + + inline void Warn(const EventId &event_id, + nostd::string_view format, + const common::KeyValueIterable &attributes) noexcept + { + this->Log(Severity::kWarn, event_id, format, attributes); + } + + inline void Warn(int64_t event_id, + nostd::string_view format, + const common::KeyValueIterable &attributes) noexcept + { + this->Log(Severity::kWarn, EventId{event_id}, format, attributes); + } + + inline void Warn(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept + { + this->Log(Severity::kWarn, format, attributes); + } + + inline void Warn(nostd::string_view message) noexcept { this->Log(Severity::kWarn, message); } + + inline void Error(const EventId &event_id, + nostd::string_view format, + const common::KeyValueIterable &attributes) noexcept + { + this->Log(Severity::kError, event_id, format, attributes); + } + + inline void Error(int64_t event_id, + nostd::string_view format, + const common::KeyValueIterable &attributes) noexcept + { + this->Log(Severity::kError, EventId{event_id}, format, attributes); + } + + inline void Error(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept + { + this->Log(Severity::kError, format, attributes); + } + + inline void Error(nostd::string_view message) noexcept { this->Log(Severity::kError, message); } + + inline void Fatal(const EventId &event_id, + nostd::string_view format, + const common::KeyValueIterable &attributes) noexcept + { + this->Log(Severity::kFatal, event_id, format, attributes); + } + + inline void Fatal(int64_t event_id, + nostd::string_view format, + const common::KeyValueIterable &attributes) noexcept + { + this->Log(Severity::kFatal, EventId{event_id}, format, attributes); + } + + inline void Fatal(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept + { + this->Log(Severity::kFatal, format, attributes); + } + + inline void Fatal(nostd::string_view message) noexcept { this->Log(Severity::kFatal, message); } + + // + // End of OpenTelemetry C++ user-facing Log API. + // + +protected: + // TODO: discuss with community about naming for internal methods. + virtual bool EnabledImplementation(Severity /*severity*/, + const EventId & /*event_id*/) const noexcept + { + return false; + } + + virtual bool EnabledImplementation(Severity /*severity*/, int64_t /*event_id*/) const noexcept + { + return false; + } + + void SetMinimumSeverity(uint8_t severity_or_max) noexcept + { + OPENTELEMETRY_ATOMIC_WRITE_8(&minimum_severity_, severity_or_max); + } + +private: + template + void IgnoreTraitResult(ValueType &&...) + {} + + // + // minimum_severity_ can be updated concurrently by multiple threads/cores, so race condition on + // read/write should be handled. And std::atomic can not be used here because it is not ABI + // compatible for OpenTelemetry C++ API. + // + mutable uint8_t minimum_severity_{kMaxSeverity}; +}; +} // namespace logs +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/logger_provider.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/logger_provider.h new file mode 100644 index 000000000..ab1493c5c --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/logger_provider.h @@ -0,0 +1,71 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/common/key_value_iterable.h" +#include "opentelemetry/common/key_value_iterable_view.h" +#include "opentelemetry/nostd/shared_ptr.h" +#include "opentelemetry/nostd/span.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/nostd/type_traits.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace logs +{ + +class Logger; + +/** + * Creates new Logger instances. + */ +class OPENTELEMETRY_EXPORT LoggerProvider +{ +public: + virtual ~LoggerProvider() = default; + + /** + * Gets or creates a named Logger instance. + * + * Optionally a version can be passed to create a named and versioned Logger + * instance. + * + * Optionally a configuration file name can be passed to create a configuration for + * the Logger instance. + * + */ + + virtual nostd::shared_ptr GetLogger( + nostd::string_view logger_name, + nostd::string_view library_name = "", + nostd::string_view library_version = "", + nostd::string_view schema_url = "", + const common::KeyValueIterable &attributes = common::NoopKeyValueIterable()) = 0; + + nostd::shared_ptr GetLogger( + nostd::string_view logger_name, + nostd::string_view library_name, + nostd::string_view library_version, + nostd::string_view schema_url, + std::initializer_list> attributes) + { + return GetLogger(logger_name, library_name, library_version, schema_url, + nostd::span>{ + attributes.begin(), attributes.end()}); + } + + template ::value> * = nullptr> + nostd::shared_ptr GetLogger(nostd::string_view logger_name, + nostd::string_view library_name, + nostd::string_view library_version, + nostd::string_view schema_url, + const T &attributes) + { + return GetLogger(logger_name, library_name, library_version, schema_url, + common::KeyValueIterableView(attributes)); + } +}; +} // namespace logs +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/logger_type_traits.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/logger_type_traits.h new file mode 100644 index 000000000..d88a6ffbd --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/logger_type_traits.h @@ -0,0 +1,204 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include +#include + +#include "opentelemetry/common/attribute_value.h" +#include "opentelemetry/common/key_value_iterable.h" +#include "opentelemetry/common/timestamp.h" +#include "opentelemetry/logs/event_id.h" +#include "opentelemetry/logs/log_record.h" +#include "opentelemetry/logs/severity.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/nostd/type_traits.h" +#include "opentelemetry/trace/span_context.h" +#include "opentelemetry/trace/span_id.h" +#include "opentelemetry/trace/trace_flags.h" +#include "opentelemetry/trace/trace_id.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace logs +{ +namespace detail +{ +template +struct LogRecordSetterTrait; + +template <> +struct LogRecordSetterTrait +{ + template + inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept + { + log_record->SetSeverity(std::forward(arg)); + + return log_record; + } +}; + +template <> +struct LogRecordSetterTrait +{ + template + inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept + { + log_record->SetEventId(arg.id_, nostd::string_view{arg.name_.get()}); + + return log_record; + } +}; + +template <> +struct LogRecordSetterTrait +{ + template + inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept + { + log_record->SetSpanId(arg.span_id()); + log_record->SetTraceId(arg.trace_id()); + log_record->SetTraceFlags(arg.trace_flags()); + + return log_record; + } +}; + +template <> +struct LogRecordSetterTrait +{ + template + inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept + { + log_record->SetSpanId(std::forward(arg)); + + return log_record; + } +}; + +template <> +struct LogRecordSetterTrait +{ + template + inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept + { + log_record->SetTraceId(std::forward(arg)); + + return log_record; + } +}; + +template <> +struct LogRecordSetterTrait +{ + template + inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept + { + log_record->SetTraceFlags(std::forward(arg)); + + return log_record; + } +}; + +template <> +struct LogRecordSetterTrait +{ + template + inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept + { + log_record->SetTimestamp(std::forward(arg)); + + return log_record; + } +}; + +template <> +struct LogRecordSetterTrait +{ + template + inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept + { + log_record->SetTimestamp(common::SystemTimestamp(std::forward(arg))); + + return log_record; + } +}; + +template <> +struct LogRecordSetterTrait +{ + template + inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept + { + arg.ForEachKeyValue( + [&log_record](nostd::string_view key, common::AttributeValue value) noexcept { + log_record->SetAttribute(key, value); + return true; + }); + + return log_record; + } +}; + +template +struct LogRecordSetterTrait +{ + static_assert(!std::is_same, ValueType>::value && + !std::is_same, ValueType>::value, + "unique_ptr is not allowed, please use std::move()"); + + template ::value || + std::is_convertible::value, + void> * = nullptr> + inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept + { + log_record->SetBody(std::forward(arg)); + + return log_record; + } + + template ::value, bool> + * = nullptr> + inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept + { + return LogRecordSetterTrait::Set(log_record, + std::forward(arg)); + } + + template ::value, int> * = + nullptr> + inline static LogRecord *Set(LogRecord *log_record, ArgumentType &&arg) noexcept + { + for (auto &argv : arg) + { + log_record->SetAttribute(argv.first, argv.second); + } + + return log_record; + } +}; + +template +struct LogRecordHasType; + +template +struct LogRecordHasType : public std::false_type +{}; + +template +struct LogRecordHasType + : public std::conditional::value, + std::true_type, + LogRecordHasType>::type +{}; + +} // namespace detail + +} // namespace logs +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/noop.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/noop.h new file mode 100644 index 000000000..24312f061 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/noop.h @@ -0,0 +1,131 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +// Please refer to provider.h for documentation on how to obtain a Logger object. +// +// This file is part of the internal implementation of OpenTelemetry. Nothing in this file should be +// used directly. Please refer to logger.h for documentation on these interfaces. + +#include "opentelemetry/logs/event_logger.h" +#include "opentelemetry/logs/event_logger_provider.h" +#include "opentelemetry/logs/logger.h" +#include "opentelemetry/logs/logger_provider.h" +#include "opentelemetry/nostd/shared_ptr.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/nostd/unique_ptr.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace common +{ +class KeyValueIterable; +} // namespace common + +namespace logs +{ +/** + * No-op implementation of Logger. This class should not be used directly. It should only be + * instantiated using a LoggerProvider's GetLogger() call. + */ +class NoopLogger final : public Logger +{ +public: + const nostd::string_view GetName() noexcept override { return "noop logger"; } + + nostd::unique_ptr CreateLogRecord() noexcept override + { + /* + * Do not return memory shared between threads, + * a `new` + `delete` for each noop record can not be avoided, + * due to the semantic of unique_ptr. + */ + return nostd::unique_ptr(new NoopLogRecord()); + } + + using Logger::EmitLogRecord; + + void EmitLogRecord(nostd::unique_ptr &&) noexcept override {} + +private: + class NoopLogRecord : public LogRecord + { + public: + NoopLogRecord() = default; + ~NoopLogRecord() override = default; + + void SetTimestamp(common::SystemTimestamp /* timestamp */) noexcept override {} + void SetObservedTimestamp(common::SystemTimestamp /* timestamp */) noexcept override {} + void SetSeverity(logs::Severity /* severity */) noexcept override {} + void SetBody(const common::AttributeValue & /* message */) noexcept override {} + void SetAttribute(nostd::string_view /* key */, + const common::AttributeValue & /* value */) noexcept override + {} + void SetEventId(int64_t /* id */, nostd::string_view /* name */) noexcept override {} + void SetTraceId(const trace::TraceId & /* trace_id */) noexcept override {} + void SetSpanId(const trace::SpanId & /* span_id */) noexcept override {} + void SetTraceFlags(const trace::TraceFlags & /* trace_flags */) noexcept override {} + }; +}; + +/** + * No-op implementation of a LoggerProvider. + */ +class NoopLoggerProvider final : public LoggerProvider +{ +public: + NoopLoggerProvider() : logger_{nostd::shared_ptr(new NoopLogger())} {} + + nostd::shared_ptr GetLogger(nostd::string_view /* logger_name */, + nostd::string_view /* library_name */, + nostd::string_view /* library_version */, + nostd::string_view /* schema_url */, + const common::KeyValueIterable & /* attributes */) override + { + return logger_; + } + +private: + nostd::shared_ptr logger_; +}; + +#if OPENTELEMETRY_ABI_VERSION_NO < 2 +class NoopEventLogger final : public EventLogger +{ +public: + NoopEventLogger() : logger_{nostd::shared_ptr(new NoopLogger())} {} + + const nostd::string_view GetName() noexcept override { return "noop event logger"; } + + nostd::shared_ptr GetDelegateLogger() noexcept override { return logger_; } + + void EmitEvent(nostd::string_view, nostd::unique_ptr &&) noexcept override {} + +private: + nostd::shared_ptr logger_; +}; + +/** + * No-op implementation of a EventLoggerProvider. + */ +class NoopEventLoggerProvider final : public EventLoggerProvider +{ +public: + NoopEventLoggerProvider() : event_logger_{nostd::shared_ptr(new NoopEventLogger())} + {} + + nostd::shared_ptr CreateEventLogger( + nostd::shared_ptr /*delegate_logger*/, + nostd::string_view /*event_domain*/) noexcept override + { + return event_logger_; + } + +private: + nostd::shared_ptr event_logger_; +}; +#endif + +} // namespace logs +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/provider.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/provider.h new file mode 100644 index 000000000..0c1b4deea --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/provider.h @@ -0,0 +1,100 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +#include "opentelemetry/common/macros.h" +#include "opentelemetry/common/spin_lock_mutex.h" +#include "opentelemetry/logs/noop.h" +#include "opentelemetry/nostd/shared_ptr.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace logs +{ + +#if OPENTELEMETRY_ABI_VERSION_NO < 2 +class EventLoggerProvider; +#endif +class LoggerProvider; + +/** + * Stores the singleton global LoggerProvider. + */ +class OPENTELEMETRY_EXPORT Provider +{ +public: + /** + * Returns the singleton LoggerProvider. + * + * By default, a no-op LoggerProvider is returned. This will never return a + * nullptr LoggerProvider. + */ + static nostd::shared_ptr GetLoggerProvider() noexcept + { + std::lock_guard guard(GetLock()); + return nostd::shared_ptr(GetProvider()); + } + + /** + * Changes the singleton LoggerProvider. + */ + static void SetLoggerProvider(const nostd::shared_ptr &tp) noexcept + { + std::lock_guard guard(GetLock()); + GetProvider() = tp; + } + +#if OPENTELEMETRY_ABI_VERSION_NO < 2 + /** + * Returns the singleton EventLoggerProvider. + * + * By default, a no-op EventLoggerProvider is returned. This will never return a + * nullptr EventLoggerProvider. + */ + OPENTELEMETRY_DEPRECATED static nostd::shared_ptr + GetEventLoggerProvider() noexcept + { + std::lock_guard guard(GetLock()); + return nostd::shared_ptr(GetEventProvider()); + } + + /** + * Changes the singleton EventLoggerProvider. + */ + OPENTELEMETRY_DEPRECATED static void SetEventLoggerProvider( + const nostd::shared_ptr &tp) noexcept + { + std::lock_guard guard(GetLock()); + GetEventProvider() = tp; + } +#endif + +private: + OPENTELEMETRY_API_SINGLETON static nostd::shared_ptr &GetProvider() noexcept + { + static nostd::shared_ptr provider(new NoopLoggerProvider); + return provider; + } + +#if OPENTELEMETRY_ABI_VERSION_NO < 2 + OPENTELEMETRY_DEPRECATED + OPENTELEMETRY_API_SINGLETON static nostd::shared_ptr & + GetEventProvider() noexcept + { + static nostd::shared_ptr provider(new NoopEventLoggerProvider); + return provider; + } +#endif + + OPENTELEMETRY_API_SINGLETON static common::SpinLockMutex &GetLock() noexcept + { + static common::SpinLockMutex lock; + return lock; + } +}; + +} // namespace logs +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/severity.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/severity.h new file mode 100644 index 000000000..f4d961615 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/logs/severity.h @@ -0,0 +1,67 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace logs +{ + +/** + * Severity Levels assigned to log events, based on Log Data Model, + * with the addition of kInvalid (mapped to a severity number of 0). + * + * See + * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#field-severitynumber + */ +enum class Severity : uint8_t +{ + kInvalid = 0, + kTrace = 1, + kTrace2 = 2, + kTrace3 = 3, + kTrace4 = 4, + kDebug = 5, + kDebug2 = 6, + kDebug3 = 7, + kDebug4 = 8, + kInfo = 9, + kInfo2 = 10, + kInfo3 = 11, + kInfo4 = 12, + kWarn = 13, + kWarn2 = 14, + kWarn3 = 15, + kWarn4 = 16, + kError = 17, + kError2 = 18, + kError3 = 19, + kError4 = 20, + kFatal = 21, + kFatal2 = 22, + kFatal3 = 23, + kFatal4 = 24 +}; + +const uint8_t kMaxSeverity = 255; + +/** + * Mapping of the severity enum above, to a severity text string (in all caps). + * This severity text can be printed out by exporters. Capital letters follow the + * spec naming convention. + * + * Included to follow the specification's recommendation to print both + * severity number and text in each log record. + */ +const nostd::string_view SeverityNumToText[25] = { + "INVALID", "TRACE", "TRACE2", "TRACE3", "TRACE4", "DEBUG", "DEBUG2", "DEBUG3", "DEBUG4", + "INFO", "INFO2", "INFO3", "INFO4", "WARN", "WARN2", "WARN3", "WARN4", "ERROR", + "ERROR2", "ERROR3", "ERROR4", "FATAL", "FATAL2", "FATAL3", "FATAL4"}; + +} // namespace logs +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/async_instruments.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/async_instruments.h new file mode 100644 index 000000000..f73eb2f51 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/async_instruments.h @@ -0,0 +1,33 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/metrics/observer_result.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace metrics +{ + +using ObservableCallbackPtr = void (*)(ObserverResult, void *); + +class ObservableInstrument +{ +public: + ObservableInstrument() = default; + virtual ~ObservableInstrument() = default; + + /** + * Sets up a function that will be called whenever a metric collection is initiated. + */ + virtual void AddCallback(ObservableCallbackPtr, void *state) noexcept = 0; + + /** + * Remove a function that was configured to be called whenever a metric collection is initiated. + */ + virtual void RemoveCallback(ObservableCallbackPtr, void *state) noexcept = 0; +}; + +} // namespace metrics +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/meter.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/meter.h new file mode 100644 index 000000000..59cfb8782 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/meter.h @@ -0,0 +1,174 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/nostd/shared_ptr.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/nostd/unique_ptr.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace metrics +{ + +template +class Counter; + +template +class Histogram; + +template +class UpDownCounter; + +template +class Gauge; + +class ObservableInstrument; + +/** + * Handles instrument creation and provides a facility for batch recording. + * + * This class provides methods to create new metric instruments, record a + * batch of values to a specified set of instruments, and collect + * measurements from all instruments. + * + */ +class Meter +{ +public: + virtual ~Meter() = default; + + /** + * Creates a Counter with the passed characteristics and returns a unique_ptr to that Counter. + * + * @param name the name of the new Counter. + * @param description a brief description of what the Counter is used for. + * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html. + * @return a shared pointer to the created Counter. + */ + + virtual nostd::unique_ptr> CreateUInt64Counter( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept = 0; + + virtual nostd::unique_ptr> CreateDoubleCounter( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept = 0; + + /** + * Creates a Asynchronous (Observable) counter with the passed characteristics and returns a + * shared_ptr to that Observable Counter + * + * @param name the name of the new Observable Counter. + * @param description a brief description of what the Observable Counter is used for. + * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html. + */ + virtual nostd::shared_ptr CreateInt64ObservableCounter( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept = 0; + + virtual nostd::shared_ptr CreateDoubleObservableCounter( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept = 0; + + /** + * Creates a Histogram with the passed characteristics and returns a unique_ptr to that Histogram. + * + * @param name the name of the new Histogram. + * @param description a brief description of what the Histogram is used for. + * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html. + * @return a shared pointer to the created Histogram. + */ + virtual nostd::unique_ptr> CreateUInt64Histogram( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept = 0; + + virtual nostd::unique_ptr> CreateDoubleHistogram( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept = 0; + +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 + /** + * Creates a Gauge with the passed characteristics and returns a unique_ptr to that Gauge. + * + * @param name the name of the new Gauge. + * @param description a brief description of what the Gauge is used for. + * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html. + * @return a unique pointer to the created Gauge. + */ + + virtual nostd::unique_ptr> CreateInt64Gauge( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept = 0; + + virtual nostd::unique_ptr> CreateDoubleGauge( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept = 0; +#endif + + /** + * Creates a Asynchronous (Observable) Gauge with the passed characteristics and returns a + * shared_ptr to that Observable Gauge + * + * @param name the name of the new Observable Gauge. + * @param description a brief description of what the Observable Gauge is used for. + * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html. + */ + virtual nostd::shared_ptr CreateInt64ObservableGauge( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept = 0; + + virtual nostd::shared_ptr CreateDoubleObservableGauge( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept = 0; + + /** + * Creates an UpDownCounter with the passed characteristics and returns a unique_ptr to that + * UpDownCounter. + * + * @param name the name of the new UpDownCounter. + * @param description a brief description of what the UpDownCounter is used for. + * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html. + * @return a shared pointer to the created UpDownCounter. + */ + virtual nostd::unique_ptr> CreateInt64UpDownCounter( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept = 0; + + virtual nostd::unique_ptr> CreateDoubleUpDownCounter( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept = 0; + + /** + * Creates a Asynchronous (Observable) UpDownCounter with the passed characteristics and returns + * a shared_ptr to that Observable UpDownCounter + * + * @param name the name of the new Observable UpDownCounter. + * @param description a brief description of what the Observable UpDownCounter is used for. + * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html. + */ + virtual nostd::shared_ptr CreateInt64ObservableUpDownCounter( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept = 0; + + virtual nostd::shared_ptr CreateDoubleObservableUpDownCounter( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept = 0; +}; +} // namespace metrics +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/meter_provider.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/meter_provider.h new file mode 100644 index 000000000..fca960bb8 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/meter_provider.h @@ -0,0 +1,148 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/common/key_value_iterable.h" +#include "opentelemetry/common/key_value_iterable_view.h" +#include "opentelemetry/nostd/shared_ptr.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/nostd/type_traits.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace metrics +{ + +class Meter; + +/** + * Creates new Meter instances. + */ +class MeterProvider +{ +public: + virtual ~MeterProvider() = default; + +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 + + /** + * Gets or creates a named Meter instance (ABI). + * + * @since ABI_VERSION 2 + * + * @param[in] name Meter instrumentation scope + * @param[in] version Instrumentation scope version + * @param[in] schema_url Instrumentation scope schema URL + * @param[in] attributes Instrumentation scope attributes (optional, may be nullptr) + */ + virtual nostd::shared_ptr GetMeter( + nostd::string_view name, + nostd::string_view version, + nostd::string_view schema_url, + const common::KeyValueIterable *attributes) noexcept = 0; + + /** + * Gets or creates a named Meter instance (API helper). + * + * @since ABI_VERSION 2 + * + * @param[in] name Meter instrumentation scope + * @param[in] version Instrumentation scope version, optional + * @param[in] schema_url Instrumentation scope schema URL, optional + */ + nostd::shared_ptr GetMeter(nostd::string_view name, + nostd::string_view version = "", + nostd::string_view schema_url = "") + { + return GetMeter(name, version, schema_url, nullptr); + } + + /** + * Gets or creates a named Meter instance (API helper). + * + * @since ABI_VERSION 2 + * + * @param[in] name Meter instrumentation scope + * @param[in] version Instrumentation scope version + * @param[in] schema_url Instrumentation scope schema URL + * @param[in] attributes Instrumentation scope attributes + */ + nostd::shared_ptr GetMeter( + nostd::string_view name, + nostd::string_view version, + nostd::string_view schema_url, + std::initializer_list> attributes) + { + /* Build a container from std::initializer_list. */ + nostd::span> attributes_span{ + attributes.begin(), attributes.end()}; + + /* Build a view on the container. */ + common::KeyValueIterableView< + nostd::span>> + iterable_attributes{attributes_span}; + + /* Add attributes using the view. */ + return GetMeter(name, version, schema_url, &iterable_attributes); + } + + /** + * Gets or creates a named Meter instance (API helper). + * + * @since ABI_VERSION 2 + * + * @param[in] name Meter instrumentation scope + * @param[in] version Instrumentation scope version + * @param[in] schema_url Instrumentation scope schema URL + * @param[in] attributes Instrumentation scope attributes container + */ + template ::value> * = nullptr> + nostd::shared_ptr GetMeter(nostd::string_view name, + nostd::string_view version, + nostd::string_view schema_url, + const T &attributes) + { + /* Build a view on the container. */ + common::KeyValueIterableView iterable_attributes(attributes); + + /* Add attributes using the view. */ + return GetMeter(name, version, schema_url, &iterable_attributes); + } + +#else + /** + * Gets or creates a named Meter instance (ABI) + * + * @since ABI_VERSION 1 + * + * @param[in] name Meter instrumentation scope + * @param[in] version Instrumentation scope version, optional + * @param[in] schema_url Instrumentation scope schema URL, optional + */ + virtual nostd::shared_ptr GetMeter(nostd::string_view name, + nostd::string_view version = "", + nostd::string_view schema_url = "") noexcept = 0; +#endif + +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 + /** + * Remove a named Meter instance (ABI). + * + * This API is experimental, see + * https://github.com/open-telemetry/opentelemetry-specification/issues/2232 + * + * @since ABI_VERSION 2 + * + * @param[in] name Meter instrumentation scope + * @param[in] version Instrumentation scope version, optional + * @param[in] schema_url Instrumentation scope schema URL, optional + */ + virtual void RemoveMeter(nostd::string_view name, + nostd::string_view version = "", + nostd::string_view schema_url = "") noexcept = 0; +#endif +}; +} // namespace metrics +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/noop.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/noop.h new file mode 100644 index 000000000..1d508b938 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/noop.h @@ -0,0 +1,271 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/metrics/async_instruments.h" +#include "opentelemetry/metrics/meter.h" +#include "opentelemetry/metrics/meter_provider.h" +#include "opentelemetry/metrics/observer_result.h" +#include "opentelemetry/metrics/sync_instruments.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace metrics +{ + +template +class NoopCounter : public Counter +{ +public: + NoopCounter(nostd::string_view /* name */, + nostd::string_view /* description */, + nostd::string_view /* unit */) noexcept + {} + void Add(T /* value */) noexcept override {} + void Add(T /* value */, const context::Context & /* context */) noexcept override {} + void Add(T /* value */, const common::KeyValueIterable & /* attributes */) noexcept override {} + void Add(T /* value */, + const common::KeyValueIterable & /* attributes */, + const context::Context & /* context */) noexcept override + {} +}; + +template +class NoopHistogram : public Histogram +{ +public: + NoopHistogram(nostd::string_view /* name */, + nostd::string_view /* description */, + nostd::string_view /* unit */) noexcept + {} + void Record(T /* value */, const context::Context & /* context */) noexcept override {} + void Record(T /* value */, + const common::KeyValueIterable & /* attributes */, + const context::Context & /* context */) noexcept override + {} +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 + void Record(T /*value*/, + const opentelemetry::common::KeyValueIterable & /*attributes*/) noexcept override + {} + + void Record(T /*value*/) noexcept override {} +#endif +}; + +template +class NoopUpDownCounter : public UpDownCounter +{ +public: + NoopUpDownCounter(nostd::string_view /* name */, + nostd::string_view /* description */, + nostd::string_view /* unit */) noexcept + {} + ~NoopUpDownCounter() override = default; + void Add(T /* value */) noexcept override {} + void Add(T /* value */, const context::Context & /* context */) noexcept override {} + void Add(T /* value */, const common::KeyValueIterable & /* attributes */) noexcept override {} + void Add(T /* value */, + const common::KeyValueIterable & /* attributes */, + const context::Context & /* context */) noexcept override + {} +}; + +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 +template +class NoopGauge : public Gauge +{ +public: + NoopGauge(nostd::string_view /* name */, + nostd::string_view /* description */, + nostd::string_view /* unit */) noexcept + {} + ~NoopGauge() override = default; + void Record(T /* value */) noexcept override {} + void Record(T /* value */, const context::Context & /* context */) noexcept override {} + void Record(T /* value */, const common::KeyValueIterable & /* attributes */) noexcept override {} + void Record(T /* value */, + const common::KeyValueIterable & /* attributes */, + const context::Context & /* context */) noexcept override + {} +}; +#endif + +class NoopObservableInstrument : public ObservableInstrument +{ +public: + NoopObservableInstrument(nostd::string_view /* name */, + nostd::string_view /* description */, + nostd::string_view /* unit */) noexcept + {} + + void AddCallback(ObservableCallbackPtr, void * /* state */) noexcept override {} + void RemoveCallback(ObservableCallbackPtr, void * /* state */) noexcept override {} +}; + +/** + * No-op implementation of Meter. + */ +class NoopMeter final : public Meter +{ +public: + nostd::unique_ptr> CreateUInt64Counter( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override + { + return nostd::unique_ptr>{new NoopCounter(name, description, unit)}; + } + + nostd::unique_ptr> CreateDoubleCounter( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override + { + return nostd::unique_ptr>{new NoopCounter(name, description, unit)}; + } + + nostd::shared_ptr CreateInt64ObservableCounter( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override + { + return nostd::shared_ptr( + new NoopObservableInstrument(name, description, unit)); + } + + nostd::shared_ptr CreateDoubleObservableCounter( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override + { + return nostd::shared_ptr( + new NoopObservableInstrument(name, description, unit)); + } + + nostd::unique_ptr> CreateUInt64Histogram( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override + { + return nostd::unique_ptr>{ + new NoopHistogram(name, description, unit)}; + } + + nostd::unique_ptr> CreateDoubleHistogram( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override + { + return nostd::unique_ptr>{new NoopHistogram(name, description, unit)}; + } + +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 + nostd::unique_ptr> CreateInt64Gauge(nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override + { + return nostd::unique_ptr>{new NoopGauge(name, description, unit)}; + } + + nostd::unique_ptr> CreateDoubleGauge(nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override + { + return nostd::unique_ptr>{new NoopGauge(name, description, unit)}; + } +#endif + + nostd::shared_ptr CreateInt64ObservableGauge( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override + { + return nostd::shared_ptr( + new NoopObservableInstrument(name, description, unit)); + } + + nostd::shared_ptr CreateDoubleObservableGauge( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override + { + return nostd::shared_ptr( + new NoopObservableInstrument(name, description, unit)); + } + + nostd::unique_ptr> CreateInt64UpDownCounter( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override + { + return nostd::unique_ptr>{ + new NoopUpDownCounter(name, description, unit)}; + } + + nostd::unique_ptr> CreateDoubleUpDownCounter( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override + { + return nostd::unique_ptr>{ + new NoopUpDownCounter(name, description, unit)}; + } + + nostd::shared_ptr CreateInt64ObservableUpDownCounter( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override + { + return nostd::shared_ptr( + new NoopObservableInstrument(name, description, unit)); + } + + nostd::shared_ptr CreateDoubleObservableUpDownCounter( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override + { + return nostd::shared_ptr( + new NoopObservableInstrument(name, description, unit)); + } +}; + +/** + * No-op implementation of a MeterProvider. + */ +class NoopMeterProvider final : public MeterProvider +{ +public: + NoopMeterProvider() : meter_{nostd::shared_ptr(new NoopMeter)} {} + +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 + nostd::shared_ptr GetMeter( + nostd::string_view /* name */, + nostd::string_view /* version */, + nostd::string_view /* schema_url */, + const common::KeyValueIterable * /* attributes */) noexcept override + { + return meter_; + } +#else + nostd::shared_ptr GetMeter(nostd::string_view /* name */, + nostd::string_view /* version */, + nostd::string_view /* schema_url */) noexcept override + { + return meter_; + } +#endif + +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 + void RemoveMeter(nostd::string_view /* name */, + nostd::string_view /* version */, + nostd::string_view /* schema_url */) noexcept override + {} +#endif + +private: + nostd::shared_ptr meter_; +}; +} // namespace metrics +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/observer_result.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/observer_result.h new file mode 100644 index 000000000..56c42bc20 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/observer_result.h @@ -0,0 +1,54 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/common/attribute_value.h" +#include "opentelemetry/common/key_value_iterable_view.h" +#include "opentelemetry/nostd/shared_ptr.h" +#include "opentelemetry/nostd/span.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/nostd/type_traits.h" +#include "opentelemetry/nostd/variant.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace metrics +{ + +/** + * ObserverResultT class is necessary for the callback recording asynchronous + * instrument use. + */ +template +class ObserverResultT +{ + +public: + virtual ~ObserverResultT() = default; + + virtual void Observe(T value) noexcept = 0; + + virtual void Observe(T value, const common::KeyValueIterable &attributes) noexcept = 0; + + template ::value> * = nullptr> + void Observe(T value, const U &attributes) noexcept + { + this->Observe(value, common::KeyValueIterableView{attributes}); + } + + void Observe(T value, + std::initializer_list> + attributes) noexcept + { + this->Observe(value, nostd::span>{ + attributes.begin(), attributes.end()}); + } +}; + +using ObserverResult = nostd::variant>, + nostd::shared_ptr>>; + +} // namespace metrics +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/provider.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/provider.h new file mode 100644 index 000000000..20a606a77 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/provider.h @@ -0,0 +1,60 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +#include "opentelemetry/common/spin_lock_mutex.h" +#include "opentelemetry/metrics/meter_provider.h" +#include "opentelemetry/metrics/noop.h" +#include "opentelemetry/nostd/shared_ptr.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace metrics +{ + +/** + * Stores the singleton global MeterProvider. + */ +class Provider +{ +public: + /** + * Returns the singleton MeterProvider. + * + * By default, a no-op MeterProvider is returned. This will never return a + * nullptr MeterProvider. + */ + static nostd::shared_ptr GetMeterProvider() noexcept + { + std::lock_guard guard(GetLock()); + return nostd::shared_ptr(GetProvider()); + } + + /** + * Changes the singleton MeterProvider. + */ + static void SetMeterProvider(const nostd::shared_ptr &tp) noexcept + { + std::lock_guard guard(GetLock()); + GetProvider() = tp; + } + +private: + OPENTELEMETRY_API_SINGLETON static nostd::shared_ptr &GetProvider() noexcept + { + static nostd::shared_ptr provider(new NoopMeterProvider); + return provider; + } + + OPENTELEMETRY_API_SINGLETON static common::SpinLockMutex &GetLock() noexcept + { + static common::SpinLockMutex lock; + return lock; + } +}; + +} // namespace metrics +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/sync_instruments.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/sync_instruments.h new file mode 100644 index 000000000..9eaec3352 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/metrics/sync_instruments.h @@ -0,0 +1,328 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/common/attribute_value.h" +#include "opentelemetry/common/key_value_iterable_view.h" +#include "opentelemetry/context/context.h" +#include "opentelemetry/nostd/span.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/nostd/type_traits.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace metrics +{ + +class SynchronousInstrument +{ +public: + SynchronousInstrument() = default; + virtual ~SynchronousInstrument() = default; +}; + +/* A Counter instrument that adds values. */ +template +class Counter : public SynchronousInstrument +{ + +public: + /** + * Record a value + * + * @param value The increment amount. MUST be non-negative. + */ + virtual void Add(T value) noexcept = 0; + + /** + * Record a value + * + * @param value The increment amount. MUST be non-negative. + * @param context The explicit context to associate with this measurement. + */ + virtual void Add(T value, const context::Context &context) noexcept = 0; + + /** + * Record a value with a set of attributes. + * + * @param value The increment amount. MUST be non-negative. + * @param attributes A set of attributes to associate with the value. + */ + + virtual void Add(T value, const common::KeyValueIterable &attributes) noexcept = 0; + + /** + * Record a value with a set of attributes. + * + * @param value The increment amount. MUST be non-negative. + * @param attributes A set of attributes to associate with the value. + * @param context The explicit context to associate with this measurement. + */ + virtual void Add(T value, + const common::KeyValueIterable &attributes, + const context::Context &context) noexcept = 0; + + template ::value> * = nullptr> + void Add(T value, const U &attributes) noexcept + { + this->Add(value, common::KeyValueIterableView{attributes}); + } + + template ::value> * = nullptr> + void Add(T value, const U &attributes, const context::Context &context) noexcept + { + this->Add(value, common::KeyValueIterableView{attributes}, context); + } + + void Add(T value, + std::initializer_list> + attributes) noexcept + { + this->Add(value, nostd::span>{ + attributes.begin(), attributes.end()}); + } + + void Add(T value, + std::initializer_list> attributes, + const context::Context &context) noexcept + { + this->Add(value, + nostd::span>{ + attributes.begin(), attributes.end()}, + context); + } +}; + +/** A histogram instrument that records values. */ + +template +class Histogram : public SynchronousInstrument +{ +public: +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 + /** + * @since ABI_VERSION 2 + * Records a value. + * + * @param value The measurement value. MUST be non-negative. + */ + virtual void Record(T value) noexcept = 0; + + /** + * @since ABI_VERSION 2 + * Records a value with a set of attributes. + * + * @param value The measurement value. MUST be non-negative. + * @param attribute A set of attributes to associate with the value. + */ + virtual void Record(T value, const common::KeyValueIterable &attribute) noexcept = 0; + + template ::value> * = nullptr> + void Record(T value, const U &attributes) noexcept + { + this->Record(value, common::KeyValueIterableView{attributes}); + } + + void Record(T value, + std::initializer_list> + attributes) noexcept + { + this->Record(value, nostd::span>{ + attributes.begin(), attributes.end()}); + } +#endif + + /** + * Records a value. + * + * @param value The measurement value. MUST be non-negative. + * @param context The explicit context to associate with this measurement. + */ + virtual void Record(T value, const context::Context &context) noexcept = 0; + + /** + * Records a value with a set of attributes. + * + * @param value The measurement value. MUST be non-negative. + * @param attributes A set of attributes to associate with the value.. + * @param context The explicit context to associate with this measurement. + */ + virtual void Record(T value, + const common::KeyValueIterable &attributes, + const context::Context &context) noexcept = 0; + + template ::value> * = nullptr> + void Record(T value, const U &attributes, const context::Context &context) noexcept + { + this->Record(value, common::KeyValueIterableView{attributes}, context); + } + + void Record( + T value, + std::initializer_list> attributes, + const context::Context &context) noexcept + { + this->Record(value, + nostd::span>{ + attributes.begin(), attributes.end()}, + context); + } +}; + +/** An up-down-counter instrument that adds or reduce values. */ + +template +class UpDownCounter : public SynchronousInstrument +{ +public: + /** + * Record a value. + * + * @param value The increment amount. May be positive, negative or zero. + */ + virtual void Add(T value) noexcept = 0; + + /** + * Record a value. + * + * @param value The increment amount. May be positive, negative or zero. + * @param context The explicit context to associate with this measurement. + */ + virtual void Add(T value, const context::Context &context) noexcept = 0; + + /** + * Record a value with a set of attributes. + * + * @param value The increment amount. May be positive, negative or zero. + * @param attributes A set of attributes to associate with the count. + */ + virtual void Add(T value, const common::KeyValueIterable &attributes) noexcept = 0; + + /** + * Record a value with a set of attributes. + * + * @param value The increment amount. May be positive, negative or zero. + * @param attributes A set of attributes to associate with the count. + * @param context The explicit context to associate with this measurement. + */ + virtual void Add(T value, + const common::KeyValueIterable &attributes, + const context::Context &context) noexcept = 0; + + template ::value> * = nullptr> + void Add(T value, const U &attributes) noexcept + { + this->Add(value, common::KeyValueIterableView{attributes}); + } + + template ::value> * = nullptr> + void Add(T value, const U &attributes, const context::Context &context) noexcept + { + this->Add(value, common::KeyValueIterableView{attributes}, context); + } + + void Add(T value, + std::initializer_list> + attributes) noexcept + { + this->Add(value, nostd::span>{ + attributes.begin(), attributes.end()}); + } + + void Add(T value, + std::initializer_list> attributes, + const context::Context &context) noexcept + { + this->Add(value, + nostd::span>{ + attributes.begin(), attributes.end()}, + context); + } +}; + +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 +/* A Gauge instrument that records values. */ +template +class Gauge : public SynchronousInstrument +{ + +public: + /** + * Record a value + * + * @param value The measurement value. May be positive, negative or zero. + */ + virtual void Record(T value) noexcept = 0; + + /** + * Record a value + * + * @param value The measurement value. May be positive, negative or zero. + * @param context The explicit context to associate with this measurement. + */ + virtual void Record(T value, const context::Context &context) noexcept = 0; + + /** + * Record a value with a set of attributes. + * + * @param value The measurement value. May be positive, negative or zero. + * @param attributes A set of attributes to associate with the value. + */ + + virtual void Record(T value, const common::KeyValueIterable &attributes) noexcept = 0; + + /** + * Record a value with a set of attributes. + * + * @param value The measurement value. May be positive, negative or zero. + * @param attributes A set of attributes to associate with the value. + * @param context The explicit context to associate with this measurement. + */ + virtual void Record(T value, + const common::KeyValueIterable &attributes, + const context::Context &context) noexcept = 0; + + template ::value> * = nullptr> + void Record(T value, const U &attributes) noexcept + { + this->Record(value, common::KeyValueIterableView{attributes}); + } + + template ::value> * = nullptr> + void Record(T value, const U &attributes, const context::Context &context) noexcept + { + this->Record(value, common::KeyValueIterableView{attributes}, context); + } + + void Record(T value, + std::initializer_list> + attributes) noexcept + { + this->Record(value, nostd::span>{ + attributes.begin(), attributes.end()}); + } + + void Record( + T value, + std::initializer_list> attributes, + const context::Context &context) noexcept + { + this->Record(value, + nostd::span>{ + attributes.begin(), attributes.end()}, + context); + } +}; +#endif + +} // namespace metrics +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/all.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/all.h new file mode 100644 index 000000000..deaf3ac6f --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/all.h @@ -0,0 +1,21 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +#include "opentelemetry/nostd/utility.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace nostd +{ +namespace detail +{ +template +using all = std::is_same, integer_sequence>; + +} // namespace detail +} // namespace nostd +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/decay.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/decay.h new file mode 100644 index 000000000..a6cb11124 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/decay.h @@ -0,0 +1,16 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace nostd +{ +template +using decay_t = typename std::decay::type; +} // namespace nostd +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/dependent_type.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/dependent_type.h new file mode 100644 index 000000000..5bba09ff8 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/dependent_type.h @@ -0,0 +1,20 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace nostd +{ +namespace detail +{ +template +struct dependent_type : T +{}; +} // namespace detail +} // namespace nostd +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/functional.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/functional.h new file mode 100644 index 000000000..0da58dd18 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/functional.h @@ -0,0 +1,66 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +#include "opentelemetry/version.h" + +#define OPENTELEMETRY_RETURN(...) \ + noexcept(noexcept(__VA_ARGS__))->decltype(__VA_ARGS__) \ + { \ + return __VA_ARGS__; \ + } + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace nostd +{ +namespace detail +{ +struct equal_to +{ + template + inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const + OPENTELEMETRY_RETURN(std::forward(lhs) == std::forward(rhs)) +}; + +struct not_equal_to +{ + template + inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const + OPENTELEMETRY_RETURN(std::forward(lhs) != std::forward(rhs)) +}; + +struct less +{ + template + inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const + OPENTELEMETRY_RETURN(std::forward(lhs) < std::forward(rhs)) +}; + +struct greater +{ + template + inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const + OPENTELEMETRY_RETURN(std::forward(lhs) > std::forward(rhs)) +}; + +struct less_equal +{ + template + inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const + OPENTELEMETRY_RETURN(std::forward(lhs) <= std::forward(rhs)) +}; + +struct greater_equal +{ + template + inline constexpr auto operator()(Lhs &&lhs, Rhs &&rhs) const + OPENTELEMETRY_RETURN(std::forward(lhs) >= std::forward(rhs)) +}; +} // namespace detail +} // namespace nostd +OPENTELEMETRY_END_NAMESPACE + +#undef OPENTELEMETRY_RETURN diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/invoke.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/invoke.h new file mode 100644 index 000000000..55a943ed1 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/invoke.h @@ -0,0 +1,163 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include + +#include "opentelemetry/nostd/detail/decay.h" +#include "opentelemetry/nostd/detail/void.h" +#include "opentelemetry/version.h" + +#define OPENTELEMETRY_RETURN(...) \ + noexcept(noexcept(__VA_ARGS__))->decltype(__VA_ARGS__) \ + { \ + return __VA_ARGS__; \ + } + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace nostd +{ +namespace detail +{ + +template +struct is_reference_wrapper : std::false_type +{}; + +template +struct is_reference_wrapper> : std::true_type +{}; + +template +struct Invoke; + +template <> +struct Invoke +{ + template + inline static constexpr auto invoke(R T::*pmf, Arg &&arg, Args &&...args) + OPENTELEMETRY_RETURN((std::forward(arg).*pmf)(std::forward(args)...)) +}; + +template <> +struct Invoke +{ + template + inline static constexpr auto invoke(R T::*pmf, Arg &&arg, Args &&...args) + OPENTELEMETRY_RETURN((std::forward(arg).get().*pmf)(std::forward(args)...)) +}; + +template <> +struct Invoke +{ + template + inline static constexpr auto invoke(R T::*pmf, Arg &&arg, Args &&...args) + OPENTELEMETRY_RETURN(((*std::forward(arg)).*pmf)(std::forward(args)...)) +}; + +template <> +struct Invoke +{ + template + inline static constexpr auto invoke(R T::*pmo, Arg &&arg) + OPENTELEMETRY_RETURN(std::forward(arg).*pmo) +}; + +template <> +struct Invoke +{ + template + inline static constexpr auto invoke(R T::*pmo, Arg &&arg) + OPENTELEMETRY_RETURN(std::forward(arg).get().*pmo) +}; + +template <> +struct Invoke +{ + template + inline static constexpr auto invoke(R T::*pmo, Arg &&arg) + OPENTELEMETRY_RETURN((*std::forward(arg)).*pmo) +}; + +template +inline constexpr auto invoke_impl(R T::*f, Arg &&arg, Args &&...args) OPENTELEMETRY_RETURN( + Invoke::value, + (std::is_base_of>::value ? 0 + : is_reference_wrapper>::value ? 1 + : 2)>::invoke(f, + std::forward(arg), + std::forward(args)...)) + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4100) +#endif + template + inline constexpr auto invoke_impl(F &&f, Args &&...args) + OPENTELEMETRY_RETURN(std::forward(f)(std::forward(args)...)) +#ifdef _MSC_VER +# pragma warning(pop) +#endif +} // namespace detail + +/* clang-format off */ +template +inline constexpr auto invoke(F &&f, Args &&... args) + OPENTELEMETRY_RETURN(detail::invoke_impl(std::forward(f), std::forward(args)...)) + +namespace detail +/* clang-format on */ +{ + + template + struct invoke_result + {}; + + template + struct invoke_result(), std::declval()...))>, + F, Args...> + { + using type = decltype(nostd::invoke(std::declval(), std::declval()...)); + }; + +} // namespace detail + +template +using invoke_result = detail::invoke_result; + +template +using invoke_result_t = typename invoke_result::type; + +namespace detail +{ + +template +struct is_invocable : std::false_type +{}; + +template +struct is_invocable>, F, Args...> : std::true_type +{}; + +template +struct is_invocable_r : std::false_type +{}; + +template +struct is_invocable_r>, R, F, Args...> + : std::is_convertible, R> +{}; + +} // namespace detail + +template +using is_invocable = detail::is_invocable; + +template +using is_invocable_r = detail::is_invocable_r; +} // namespace nostd +OPENTELEMETRY_END_NAMESPACE + +#undef OPENTELEMETRY_RETURN diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/trait.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/trait.h new file mode 100644 index 000000000..8f76fdec8 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/trait.h @@ -0,0 +1,75 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +#include "opentelemetry/nostd/type_traits.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace nostd +{ +namespace detail +{ +enum class Trait +{ + TriviallyAvailable, + Available, + Unavailable +}; + +template + class IsTriviallyAvailable, + template + class IsAvailable> +inline constexpr Trait trait() +{ + return IsTriviallyAvailable::value ? Trait::TriviallyAvailable + : IsAvailable::value ? Trait::Available + : Trait::Unavailable; +} + +inline constexpr Trait common_trait_impl(Trait result) +{ + return result; +} + +template +inline constexpr Trait common_trait_impl(Trait result, Trait t, Traits... ts) +{ + return static_cast(t) > static_cast(result) ? common_trait_impl(t, ts...) + : common_trait_impl(result, ts...); +} + +template +inline constexpr Trait common_trait(Traits... ts) +{ + return common_trait_impl(Trait::TriviallyAvailable, ts...); +} + +template +struct traits +{ + static constexpr Trait copy_constructible_trait = + common_trait(trait()...); + + static constexpr Trait move_constructible_trait = + common_trait(trait()...); + + static constexpr Trait copy_assignable_trait = + common_trait(copy_constructible_trait, + trait()...); + + static constexpr Trait move_assignable_trait = + common_trait(move_constructible_trait, + trait()...); + + static constexpr Trait destructible_trait = + common_trait(trait()...); +}; +} // namespace detail +} // namespace nostd +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/type_pack_element.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/type_pack_element.h new file mode 100644 index 000000000..280d24e94 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/type_pack_element.h @@ -0,0 +1,53 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include + +#include "opentelemetry/nostd/utility.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace nostd +{ +namespace detail +{ +template +using size_constant = std::integral_constant; + +template +struct indexed_type : size_constant +{ + using type = T; +}; + +template +struct type_pack_element_impl +{ +private: + template + struct set; + + template + struct set> : indexed_type... + {}; + + template + inline static std::enable_if impl(indexed_type); + + inline static std::enable_if impl(...); + +public: + using type = decltype(impl(set>{})); +}; + +template +using type_pack_element = typename type_pack_element_impl::type; + +template +using type_pack_element_t = typename type_pack_element::type; +} // namespace detail +} // namespace nostd +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/valueless.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/valueless.h new file mode 100644 index 000000000..3b2ca7f7c --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/valueless.h @@ -0,0 +1,14 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace nostd +{ +struct valueless_t +{}; +} // namespace nostd +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/variant_alternative.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/variant_alternative.h new file mode 100644 index 000000000..cc0da9c8c --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/variant_alternative.h @@ -0,0 +1,40 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +#include "opentelemetry/nostd/detail/type_pack_element.h" +#include "opentelemetry/nostd/detail/variant_fwd.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace nostd +{ +template +struct variant_alternative; + +template +using variant_alternative_t = typename variant_alternative::type; + +template +struct variant_alternative : std::add_const> +{}; + +template +struct variant_alternative : std::add_volatile> +{}; + +template +struct variant_alternative : std::add_cv> +{}; + +template +struct variant_alternative> +{ + static_assert(I < sizeof...(Ts), "index out of bounds in `std::variant_alternative<>`"); + using type = detail::type_pack_element_t; +}; +} // namespace nostd +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/variant_fwd.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/variant_fwd.h new file mode 100644 index 000000000..6bae9659e --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/variant_fwd.h @@ -0,0 +1,14 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace nostd +{ +template +class variant; +} // namespace nostd +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/variant_size.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/variant_size.h new file mode 100644 index 000000000..d8986a222 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/variant_size.h @@ -0,0 +1,33 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +#include "opentelemetry/nostd/detail/variant_fwd.h" +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace nostd +{ +template +struct variant_size; + +template +struct variant_size : variant_size +{}; + +template +struct variant_size : variant_size +{}; + +template +struct variant_size : variant_size +{}; + +template +struct variant_size> : std::integral_constant +{}; +} // namespace nostd +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/void.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/void.h new file mode 100644 index 000000000..1b4c3b4f7 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/detail/void.h @@ -0,0 +1,28 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace nostd +{ +namespace detail +{ +template +struct voider +{ + using type = void; +}; +} // namespace detail + +/** + * Back port of std::void_t + * + * Note: voider workaround is required for gcc-4.8 to make SFINAE work + */ +template +using void_t = typename detail::voider::type; +} // namespace nostd +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/function_ref.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/function_ref.h new file mode 100644 index 000000000..6f0c2dd33 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/function_ref.h @@ -0,0 +1,94 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include // IWYU pragma: keep +#include +#include + +#include "opentelemetry/version.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace nostd +{ +template +class function_ref; // IWYU pragma: keep + +/** + * Non-owning function reference that can be used as a more performant + * replacement for std::function when ownership sematics aren't needed. + * + * See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0792r0.html + * + * Based off of https://stackoverflow.com/a/39087660/4447365 + */ +template +class function_ref +{ + void *callable_ = nullptr; + R (*invoker_)(void *, Args...) = nullptr; + + template + using FunctionPointer = decltype(std::addressof(std::declval())); + + template + void BindTo(F &f) noexcept + { + callable_ = static_cast(std::addressof(f)); + invoker_ = [](void *callable, Args... args) -> R { + return (*static_cast>(callable))(std::forward(args)...); + }; + } + + template + void BindTo(R_in (*f)(Args_in...)) noexcept + { + using F = decltype(f); + if (f == nullptr) + { + return BindTo(nullptr); + } + callable_ = reinterpret_cast(f); + invoker_ = [](void *callable, Args... args) -> R { + return (F(callable))(std::forward(args)...); + }; + } + + void BindTo(std::nullptr_t) noexcept + { + callable_ = nullptr; + invoker_ = nullptr; + } + +public: + template < + class F, + typename std::enable_if::type>::value, + int>::type = 0, + typename std::enable_if< +#if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && (_MSVC_LANG > 201402)) + // std::result_of deprecated in C++17, removed in C++20 + std::is_convertible::type, R>::value, +#else + // std::result_of since C++11 + std::is_convertible::type, R>::value, +#endif + int>::type = 0> + function_ref(F &&f) + { + BindTo(f); // not forward + } + + function_ref(std::nullptr_t) {} + + function_ref(const function_ref &) noexcept = default; + function_ref(function_ref &&) noexcept = default; + + R operator()(Args... args) const { return invoker_(callable_, std::forward(args)...); } + + explicit operator bool() const { return invoker_; } +}; +} // namespace nostd +OPENTELEMETRY_END_NAMESPACE diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/attributes.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/attributes.h new file mode 100644 index 000000000..72901a84c --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/attributes.h @@ -0,0 +1,621 @@ +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// This header file defines macros for declaring attributes for functions, +// types, and variables. +// +// These macros are used within Abseil and allow the compiler to optimize, where +// applicable, certain function calls. +// +// This file is used for both C and C++! +// +// Most macros here are exposing GCC or Clang features, and are stubbed out for +// other compilers. +// +// GCC attributes documentation: +// https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Attributes.html +// https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Variable-Attributes.html +// https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Type-Attributes.html +// +// Most attributes in this file are already supported by GCC 4.7. However, some +// of them are not supported in older version of Clang. Thus, we check +// `__has_attribute()` first. If the check fails, we check if we are on GCC and +// assume the attribute exists on GCC (which is verified on GCC 4.7). +// +// ----------------------------------------------------------------------------- +// Sanitizer Attributes +// ----------------------------------------------------------------------------- +// +// Sanitizer-related attributes are not "defined" in this file (and indeed +// are not defined as such in any file). To utilize the following +// sanitizer-related attributes within your builds, define the following macros +// within your build using a `-D` flag, along with the given value for +// `-fsanitize`: +// +// * `ADDRESS_SANITIZER` + `-fsanitize=address` (Clang, GCC 4.8) +// * `MEMORY_SANITIZER` + `-fsanitize=memory` (Clang-only) +// * `THREAD_SANITIZER + `-fsanitize=thread` (Clang, GCC 4.8+) +// * `UNDEFINED_BEHAVIOR_SANITIZER` + `-fsanitize=undefined` (Clang, GCC 4.9+) +// * `CONTROL_FLOW_INTEGRITY` + -fsanitize=cfi (Clang-only) +// +// Example: +// +// // Enable branches in the Abseil code that are tagged for ASan: +// $ bazel build --copt=-DADDRESS_SANITIZER --copt=-fsanitize=address +// --linkopt=-fsanitize=address *target* +// +// Since these macro names are only supported by GCC and Clang, we only check +// for `__GNUC__` (GCC or Clang) and the above macros. +#ifndef OTABSL_BASE_ATTRIBUTES_H_ +#define OTABSL_BASE_ATTRIBUTES_H_ + +// OTABSL_HAVE_ATTRIBUTE +// +// A function-like feature checking macro that is a wrapper around +// `__has_attribute`, which is defined by GCC 5+ and Clang and evaluates to a +// nonzero constant integer if the attribute is supported or 0 if not. +// +// It evaluates to zero if `__has_attribute` is not defined by the compiler. +// +// GCC: https://gcc.gnu.org/gcc-5/changes.html +// Clang: https://clang.llvm.org/docs/LanguageExtensions.html +#ifdef __has_attribute +#define OTABSL_HAVE_ATTRIBUTE(x) __has_attribute(x) +#else +#define OTABSL_HAVE_ATTRIBUTE(x) 0 +#endif + +// OTABSL_HAVE_CPP_ATTRIBUTE +// +// A function-like feature checking macro that accepts C++11 style attributes. +// It's a wrapper around `__has_cpp_attribute`, defined by ISO C++ SD-6 +// (https://en.cppreference.com/w/cpp/experimental/feature_test). If we don't +// find `__has_cpp_attribute`, will evaluate to 0. +#if defined(__cplusplus) && defined(__has_cpp_attribute) +// NOTE: requiring __cplusplus above should not be necessary, but +// works around https://bugs.llvm.org/show_bug.cgi?id=23435. +#define OTABSL_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#else +#define OTABSL_HAVE_CPP_ATTRIBUTE(x) 0 +#endif + +// ----------------------------------------------------------------------------- +// Function Attributes +// ----------------------------------------------------------------------------- +// +// GCC: https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html +// Clang: https://clang.llvm.org/docs/AttributeReference.html + +// OTABSL_PRINTF_ATTRIBUTE +// OTABSL_SCANF_ATTRIBUTE +// +// Tells the compiler to perform `printf` format string checking if the +// compiler supports it; see the 'format' attribute in +// . +// +// Note: As the GCC manual states, "[s]ince non-static C++ methods +// have an implicit 'this' argument, the arguments of such methods +// should be counted from two, not one." +#if OTABSL_HAVE_ATTRIBUTE(format) || (defined(__GNUC__) && !defined(__clang__)) +#define OTABSL_PRINTF_ATTRIBUTE(string_index, first_to_check) \ + __attribute__((__format__(__printf__, string_index, first_to_check))) +#define OTABSL_SCANF_ATTRIBUTE(string_index, first_to_check) \ + __attribute__((__format__(__scanf__, string_index, first_to_check))) +#else +#define OTABSL_PRINTF_ATTRIBUTE(string_index, first_to_check) +#define OTABSL_SCANF_ATTRIBUTE(string_index, first_to_check) +#endif + +// OTABSL_ATTRIBUTE_ALWAYS_INLINE +// OTABSL_ATTRIBUTE_NOINLINE +// +// Forces functions to either inline or not inline. Introduced in gcc 3.1. +#if OTABSL_HAVE_ATTRIBUTE(always_inline) || \ + (defined(__GNUC__) && !defined(__clang__)) +#define OTABSL_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline)) +#define OTABSL_HAVE_ATTRIBUTE_ALWAYS_INLINE 1 +#else +#define OTABSL_ATTRIBUTE_ALWAYS_INLINE +#endif + +#if OTABSL_HAVE_ATTRIBUTE(noinline) || (defined(__GNUC__) && !defined(__clang__)) +#define OTABSL_ATTRIBUTE_NOINLINE __attribute__((noinline)) +#define OTABSL_HAVE_ATTRIBUTE_NOINLINE 1 +#else +#define OTABSL_ATTRIBUTE_NOINLINE +#endif + +// OTABSL_ATTRIBUTE_NO_TAIL_CALL +// +// Prevents the compiler from optimizing away stack frames for functions which +// end in a call to another function. +#if OTABSL_HAVE_ATTRIBUTE(disable_tail_calls) +#define OTABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 1 +#define OTABSL_ATTRIBUTE_NO_TAIL_CALL __attribute__((disable_tail_calls)) +#elif defined(__GNUC__) && !defined(__clang__) +#define OTABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 1 +#define OTABSL_ATTRIBUTE_NO_TAIL_CALL \ + __attribute__((optimize("no-optimize-sibling-calls"))) +#else +#define OTABSL_ATTRIBUTE_NO_TAIL_CALL +#define OTABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 0 +#endif + +// OTABSL_ATTRIBUTE_WEAK +// +// Tags a function as weak for the purposes of compilation and linking. +// Weak attributes currently do not work properly in LLVM's Windows backend, +// so disable them there. See https://bugs.llvm.org/show_bug.cgi?id=37598 +// for further information. +// The MinGW compiler doesn't complain about the weak attribute until the link +// step, presumably because Windows doesn't use ELF binaries. +#if (OTABSL_HAVE_ATTRIBUTE(weak) || \ + (defined(__GNUC__) && !defined(__clang__))) && \ + !(defined(__llvm__) && defined(_WIN32)) && !defined(__MINGW32__) +#undef OTABSL_ATTRIBUTE_WEAK +#define OTABSL_ATTRIBUTE_WEAK __attribute__((weak)) +#define OTABSL_HAVE_ATTRIBUTE_WEAK 1 +#else +#define OTABSL_ATTRIBUTE_WEAK +#define OTABSL_HAVE_ATTRIBUTE_WEAK 0 +#endif + +// OTABSL_ATTRIBUTE_NONNULL +// +// Tells the compiler either (a) that a particular function parameter +// should be a non-null pointer, or (b) that all pointer arguments should +// be non-null. +// +// Note: As the GCC manual states, "[s]ince non-static C++ methods +// have an implicit 'this' argument, the arguments of such methods +// should be counted from two, not one." +// +// Args are indexed starting at 1. +// +// For non-static class member functions, the implicit `this` argument +// is arg 1, and the first explicit argument is arg 2. For static class member +// functions, there is no implicit `this`, and the first explicit argument is +// arg 1. +// +// Example: +// +// /* arg_a cannot be null, but arg_b can */ +// void Function(void* arg_a, void* arg_b) OTABSL_ATTRIBUTE_NONNULL(1); +// +// class C { +// /* arg_a cannot be null, but arg_b can */ +// void Method(void* arg_a, void* arg_b) OTABSL_ATTRIBUTE_NONNULL(2); +// +// /* arg_a cannot be null, but arg_b can */ +// static void StaticMethod(void* arg_a, void* arg_b) +// OTABSL_ATTRIBUTE_NONNULL(1); +// }; +// +// If no arguments are provided, then all pointer arguments should be non-null. +// +// /* No pointer arguments may be null. */ +// void Function(void* arg_a, void* arg_b, int arg_c) OTABSL_ATTRIBUTE_NONNULL(); +// +// NOTE: The GCC nonnull attribute actually accepts a list of arguments, but +// OTABSL_ATTRIBUTE_NONNULL does not. +#if OTABSL_HAVE_ATTRIBUTE(nonnull) || (defined(__GNUC__) && !defined(__clang__)) +#define OTABSL_ATTRIBUTE_NONNULL(arg_index) __attribute__((nonnull(arg_index))) +#else +#define OTABSL_ATTRIBUTE_NONNULL(...) +#endif + +// OTABSL_ATTRIBUTE_NORETURN +// +// Tells the compiler that a given function never returns. +#if OTABSL_HAVE_ATTRIBUTE(noreturn) || (defined(__GNUC__) && !defined(__clang__)) +#define OTABSL_ATTRIBUTE_NORETURN __attribute__((noreturn)) +#elif defined(_MSC_VER) +#define OTABSL_ATTRIBUTE_NORETURN __declspec(noreturn) +#else +#define OTABSL_ATTRIBUTE_NORETURN +#endif + +// OTABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS +// +// Tells the AddressSanitizer (or other memory testing tools) to ignore a given +// function. Useful for cases when a function reads random locations on stack, +// calls _exit from a cloned subprocess, deliberately accesses buffer +// out of bounds or does other scary things with memory. +// NOTE: GCC supports AddressSanitizer(asan) since 4.8. +// https://gcc.gnu.org/gcc-4.8/changes.html +#if defined(__GNUC__) +#define OTABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) +#else +#define OTABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS +#endif + +// OTABSL_ATTRIBUTE_NO_SANITIZE_MEMORY +// +// Tells the MemorySanitizer to relax the handling of a given function. All +// "Use of uninitialized value" warnings from such functions will be suppressed, +// and all values loaded from memory will be considered fully initialized. +// This attribute is similar to the ADDRESS_SANITIZER attribute above, but deals +// with initialized-ness rather than addressability issues. +// NOTE: MemorySanitizer(msan) is supported by Clang but not GCC. +#if defined(__clang__) +#define OTABSL_ATTRIBUTE_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory)) +#else +#define OTABSL_ATTRIBUTE_NO_SANITIZE_MEMORY +#endif + +// OTABSL_ATTRIBUTE_NO_SANITIZE_THREAD +// +// Tells the ThreadSanitizer to not instrument a given function. +// NOTE: GCC supports ThreadSanitizer(tsan) since 4.8. +// https://gcc.gnu.org/gcc-4.8/changes.html +#if defined(__GNUC__) +#define OTABSL_ATTRIBUTE_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) +#else +#define OTABSL_ATTRIBUTE_NO_SANITIZE_THREAD +#endif + +// OTABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED +// +// Tells the UndefinedSanitizer to ignore a given function. Useful for cases +// where certain behavior (eg. division by zero) is being used intentionally. +// NOTE: GCC supports UndefinedBehaviorSanitizer(ubsan) since 4.9. +// https://gcc.gnu.org/gcc-4.9/changes.html +#if defined(__GNUC__) && \ + (defined(UNDEFINED_BEHAVIOR_SANITIZER) || defined(ADDRESS_SANITIZER)) +#define OTABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED \ + __attribute__((no_sanitize("undefined"))) +#else +#define OTABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED +#endif + +// OTABSL_ATTRIBUTE_NO_SANITIZE_CFI +// +// Tells the ControlFlowIntegrity sanitizer to not instrument a given function. +// See https://clang.llvm.org/docs/ControlFlowIntegrity.html for details. +#if defined(__GNUC__) && defined(CONTROL_FLOW_INTEGRITY) +#define OTABSL_ATTRIBUTE_NO_SANITIZE_CFI __attribute__((no_sanitize("cfi"))) +#else +#define OTABSL_ATTRIBUTE_NO_SANITIZE_CFI +#endif + +// OTABSL_ATTRIBUTE_NO_SANITIZE_SAFESTACK +// +// Tells the SafeStack to not instrument a given function. +// See https://clang.llvm.org/docs/SafeStack.html for details. +#if defined(__GNUC__) && defined(SAFESTACK_SANITIZER) +#define OTABSL_ATTRIBUTE_NO_SANITIZE_SAFESTACK \ + __attribute__((no_sanitize("safe-stack"))) +#else +#define OTABSL_ATTRIBUTE_NO_SANITIZE_SAFESTACK +#endif + +// OTABSL_ATTRIBUTE_RETURNS_NONNULL +// +// Tells the compiler that a particular function never returns a null pointer. +#if OTABSL_HAVE_ATTRIBUTE(returns_nonnull) || \ + (defined(__GNUC__) && \ + (__GNUC__ > 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)) && \ + !defined(__clang__)) +#define OTABSL_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull)) +#else +#define OTABSL_ATTRIBUTE_RETURNS_NONNULL +#endif + +// OTABSL_HAVE_ATTRIBUTE_SECTION +// +// Indicates whether labeled sections are supported. Weak symbol support is +// a prerequisite. Labeled sections are not supported on Darwin/iOS. +#ifdef OTABSL_HAVE_ATTRIBUTE_SECTION +#error OTABSL_HAVE_ATTRIBUTE_SECTION cannot be directly set +#elif (OTABSL_HAVE_ATTRIBUTE(section) || \ + (defined(__GNUC__) && !defined(__clang__))) && \ + !defined(__APPLE__) && OTABSL_HAVE_ATTRIBUTE_WEAK +#define OTABSL_HAVE_ATTRIBUTE_SECTION 1 + +// OTABSL_ATTRIBUTE_SECTION +// +// Tells the compiler/linker to put a given function into a section and define +// `__start_ ## name` and `__stop_ ## name` symbols to bracket the section. +// This functionality is supported by GNU linker. Any function annotated with +// `OTABSL_ATTRIBUTE_SECTION` must not be inlined, or it will be placed into +// whatever section its caller is placed into. +// +#ifndef OTABSL_ATTRIBUTE_SECTION +#define OTABSL_ATTRIBUTE_SECTION(name) \ + __attribute__((section(#name))) __attribute__((noinline)) +#endif + + +// OTABSL_ATTRIBUTE_SECTION_VARIABLE +// +// Tells the compiler/linker to put a given variable into a section and define +// `__start_ ## name` and `__stop_ ## name` symbols to bracket the section. +// This functionality is supported by GNU linker. +#ifndef OTABSL_ATTRIBUTE_SECTION_VARIABLE +#define OTABSL_ATTRIBUTE_SECTION_VARIABLE(name) __attribute__((section(#name))) +#endif + +// OTABSL_DECLARE_ATTRIBUTE_SECTION_VARS +// +// A weak section declaration to be used as a global declaration +// for OTABSL_ATTRIBUTE_SECTION_START|STOP(name) to compile and link +// even without functions with OTABSL_ATTRIBUTE_SECTION(name). +// OTABSL_DEFINE_ATTRIBUTE_SECTION should be in the exactly one file; it's +// a no-op on ELF but not on Mach-O. +// +#ifndef OTABSL_DECLARE_ATTRIBUTE_SECTION_VARS +#define OTABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name) \ + extern char __start_##name[] OTABSL_ATTRIBUTE_WEAK; \ + extern char __stop_##name[] OTABSL_ATTRIBUTE_WEAK +#endif +#ifndef OTABSL_DEFINE_ATTRIBUTE_SECTION_VARS +#define OTABSL_INIT_ATTRIBUTE_SECTION_VARS(name) +#define OTABSL_DEFINE_ATTRIBUTE_SECTION_VARS(name) +#endif + +// OTABSL_ATTRIBUTE_SECTION_START +// +// Returns `void*` pointers to start/end of a section of code with +// functions having OTABSL_ATTRIBUTE_SECTION(name). +// Returns 0 if no such functions exist. +// One must OTABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name) for this to compile and +// link. +// +#define OTABSL_ATTRIBUTE_SECTION_START(name) \ + (reinterpret_cast(__start_##name)) +#define OTABSL_ATTRIBUTE_SECTION_STOP(name) \ + (reinterpret_cast(__stop_##name)) + +#else // !OTABSL_HAVE_ATTRIBUTE_SECTION + +#define OTABSL_HAVE_ATTRIBUTE_SECTION 0 + +// provide dummy definitions +#define OTABSL_ATTRIBUTE_SECTION(name) +#define OTABSL_ATTRIBUTE_SECTION_VARIABLE(name) +#define OTABSL_INIT_ATTRIBUTE_SECTION_VARS(name) +#define OTABSL_DEFINE_ATTRIBUTE_SECTION_VARS(name) +#define OTABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name) +#define OTABSL_ATTRIBUTE_SECTION_START(name) (reinterpret_cast(0)) +#define OTABSL_ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast(0)) + +#endif // OTABSL_ATTRIBUTE_SECTION + +// OTABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC +// +// Support for aligning the stack on 32-bit x86. +#if OTABSL_HAVE_ATTRIBUTE(force_align_arg_pointer) || \ + (defined(__GNUC__) && !defined(__clang__)) +#if defined(__i386__) +#define OTABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC \ + __attribute__((force_align_arg_pointer)) +#define OTABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0) +#elif defined(__x86_64__) +#define OTABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (1) +#define OTABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC +#else // !__i386__ && !__x86_64 +#define OTABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0) +#define OTABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC +#endif // __i386__ +#else +#define OTABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC +#define OTABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0) +#endif + +// OTABSL_MUST_USE_RESULT +// +// Tells the compiler to warn about unused results. +// +// When annotating a function, it must appear as the first part of the +// declaration or definition. The compiler will warn if the return value from +// such a function is unused: +// +// OTABSL_MUST_USE_RESULT Sprocket* AllocateSprocket(); +// AllocateSprocket(); // Triggers a warning. +// +// When annotating a class, it is equivalent to annotating every function which +// returns an instance. +// +// class OTABSL_MUST_USE_RESULT Sprocket {}; +// Sprocket(); // Triggers a warning. +// +// Sprocket MakeSprocket(); +// MakeSprocket(); // Triggers a warning. +// +// Note that references and pointers are not instances: +// +// Sprocket* SprocketPointer(); +// SprocketPointer(); // Does *not* trigger a warning. +// +// OTABSL_MUST_USE_RESULT allows using cast-to-void to suppress the unused result +// warning. For that, warn_unused_result is used only for clang but not for gcc. +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425 +// +// Note: past advice was to place the macro after the argument list. +#if OTABSL_HAVE_ATTRIBUTE(nodiscard) +#define OTABSL_MUST_USE_RESULT [[nodiscard]] +#elif defined(__clang__) && OTABSL_HAVE_ATTRIBUTE(warn_unused_result) +#define OTABSL_MUST_USE_RESULT __attribute__((warn_unused_result)) +#else +#define OTABSL_MUST_USE_RESULT +#endif + +// OTABSL_ATTRIBUTE_HOT, OTABSL_ATTRIBUTE_COLD +// +// Tells GCC that a function is hot or cold. GCC can use this information to +// improve static analysis, i.e. a conditional branch to a cold function +// is likely to be not-taken. +// This annotation is used for function declarations. +// +// Example: +// +// int foo() OTABSL_ATTRIBUTE_HOT; +#if OTABSL_HAVE_ATTRIBUTE(hot) || (defined(__GNUC__) && !defined(__clang__)) +#define OTABSL_ATTRIBUTE_HOT __attribute__((hot)) +#else +#define OTABSL_ATTRIBUTE_HOT +#endif + +#if OTABSL_HAVE_ATTRIBUTE(cold) || (defined(__GNUC__) && !defined(__clang__)) +#define OTABSL_ATTRIBUTE_COLD __attribute__((cold)) +#else +#define OTABSL_ATTRIBUTE_COLD +#endif + +// OTABSL_XRAY_ALWAYS_INSTRUMENT, OTABSL_XRAY_NEVER_INSTRUMENT, OTABSL_XRAY_LOG_ARGS +// +// We define the OTABSL_XRAY_ALWAYS_INSTRUMENT and OTABSL_XRAY_NEVER_INSTRUMENT +// macro used as an attribute to mark functions that must always or never be +// instrumented by XRay. Currently, this is only supported in Clang/LLVM. +// +// For reference on the LLVM XRay instrumentation, see +// http://llvm.org/docs/XRay.html. +// +// A function with the XRAY_ALWAYS_INSTRUMENT macro attribute in its declaration +// will always get the XRay instrumentation sleds. These sleds may introduce +// some binary size and runtime overhead and must be used sparingly. +// +// These attributes only take effect when the following conditions are met: +// +// * The file/target is built in at least C++11 mode, with a Clang compiler +// that supports XRay attributes. +// * The file/target is built with the -fxray-instrument flag set for the +// Clang/LLVM compiler. +// * The function is defined in the translation unit (the compiler honors the +// attribute in either the definition or the declaration, and must match). +// +// There are cases when, even when building with XRay instrumentation, users +// might want to control specifically which functions are instrumented for a +// particular build using special-case lists provided to the compiler. These +// special case lists are provided to Clang via the +// -fxray-always-instrument=... and -fxray-never-instrument=... flags. The +// attributes in source take precedence over these special-case lists. +// +// To disable the XRay attributes at build-time, users may define +// OTABSL_NO_XRAY_ATTRIBUTES. Do NOT define OTABSL_NO_XRAY_ATTRIBUTES on specific +// packages/targets, as this may lead to conflicting definitions of functions at +// link-time. +// +#if OTABSL_HAVE_CPP_ATTRIBUTE(clang::xray_always_instrument) && \ + !defined(OTABSL_NO_XRAY_ATTRIBUTES) +#define OTABSL_XRAY_ALWAYS_INSTRUMENT [[clang::xray_always_instrument]] +#define OTABSL_XRAY_NEVER_INSTRUMENT [[clang::xray_never_instrument]] +#if OTABSL_HAVE_CPP_ATTRIBUTE(clang::xray_log_args) +#define OTABSL_XRAY_LOG_ARGS(N) \ + [[clang::xray_always_instrument, clang::xray_log_args(N)]] +#else +#define OTABSL_XRAY_LOG_ARGS(N) [[clang::xray_always_instrument]] +#endif +#else +#define OTABSL_XRAY_ALWAYS_INSTRUMENT +#define OTABSL_XRAY_NEVER_INSTRUMENT +#define OTABSL_XRAY_LOG_ARGS(N) +#endif + +// OTABSL_ATTRIBUTE_REINITIALIZES +// +// Indicates that a member function reinitializes the entire object to a known +// state, independent of the previous state of the object. +// +// The clang-tidy check bugprone-use-after-move allows member functions marked +// with this attribute to be called on objects that have been moved from; +// without the attribute, this would result in a use-after-move warning. +#if OTABSL_HAVE_CPP_ATTRIBUTE(clang::reinitializes) +#define OTABSL_ATTRIBUTE_REINITIALIZES [[clang::reinitializes]] +#else +#define OTABSL_ATTRIBUTE_REINITIALIZES +#endif + +// ----------------------------------------------------------------------------- +// Variable Attributes +// ----------------------------------------------------------------------------- + +// OTABSL_ATTRIBUTE_UNUSED +// +// Prevents the compiler from complaining about variables that appear unused. +#if OTABSL_HAVE_ATTRIBUTE(unused) || (defined(__GNUC__) && !defined(__clang__)) +#undef OTABSL_ATTRIBUTE_UNUSED +#define OTABSL_ATTRIBUTE_UNUSED __attribute__((__unused__)) +#else +#define OTABSL_ATTRIBUTE_UNUSED +#endif + +// OTABSL_ATTRIBUTE_INITIAL_EXEC +// +// Tells the compiler to use "initial-exec" mode for a thread-local variable. +// See http://people.redhat.com/drepper/tls.pdf for the gory details. +#if OTABSL_HAVE_ATTRIBUTE(tls_model) || (defined(__GNUC__) && !defined(__clang__)) +#define OTABSL_ATTRIBUTE_INITIAL_EXEC __attribute__((tls_model("initial-exec"))) +#else +#define OTABSL_ATTRIBUTE_INITIAL_EXEC +#endif + +// OTABSL_ATTRIBUTE_PACKED +// +// Instructs the compiler not to use natural alignment for a tagged data +// structure, but instead to reduce its alignment to 1. This attribute can +// either be applied to members of a structure or to a structure in its +// entirety. Applying this attribute (judiciously) to a structure in its +// entirety to optimize the memory footprint of very commonly-used structs is +// fine. Do not apply this attribute to a structure in its entirety if the +// purpose is to control the offsets of the members in the structure. Instead, +// apply this attribute only to structure members that need it. +// +// When applying OTABSL_ATTRIBUTE_PACKED only to specific structure members the +// natural alignment of structure members not annotated is preserved. Aligned +// member accesses are faster than non-aligned member accesses even if the +// targeted microprocessor supports non-aligned accesses. +#if OTABSL_HAVE_ATTRIBUTE(packed) || (defined(__GNUC__) && !defined(__clang__)) +#define OTABSL_ATTRIBUTE_PACKED __attribute__((__packed__)) +#else +#define OTABSL_ATTRIBUTE_PACKED +#endif + +// OTABSL_ATTRIBUTE_FUNC_ALIGN +// +// Tells the compiler to align the function start at least to certain +// alignment boundary +#if OTABSL_HAVE_ATTRIBUTE(aligned) || (defined(__GNUC__) && !defined(__clang__)) +#define OTABSL_ATTRIBUTE_FUNC_ALIGN(bytes) __attribute__((aligned(bytes))) +#else +#define OTABSL_ATTRIBUTE_FUNC_ALIGN(bytes) +#endif + +// OTABSL_CONST_INIT +// +// A variable declaration annotated with the `OTABSL_CONST_INIT` attribute will +// not compile (on supported platforms) unless the variable has a constant +// initializer. This is useful for variables with static and thread storage +// duration, because it guarantees that they will not suffer from the so-called +// "static init order fiasco". Prefer to put this attribute on the most visible +// declaration of the variable, if there's more than one, because code that +// accesses the variable can then use the attribute for optimization. +// +// Example: +// +// class MyClass { +// public: +// OTABSL_CONST_INIT static MyType my_var; +// }; +// +// MyType MyClass::my_var = MakeMyType(...); +// +// Note that this attribute is redundant if the variable is declared constexpr. +#if OTABSL_HAVE_CPP_ATTRIBUTE(clang::require_constant_initialization) +#define OTABSL_CONST_INIT [[clang::require_constant_initialization]] +#else +#define OTABSL_CONST_INIT +#endif // OTABSL_HAVE_CPP_ATTRIBUTE(clang::require_constant_initialization) + +#endif // OTABSL_BASE_ATTRIBUTES_H_ diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/config.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/config.h new file mode 100644 index 000000000..e0836b9b3 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/config.h @@ -0,0 +1,671 @@ +// +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ----------------------------------------------------------------------------- +// File: config.h +// ----------------------------------------------------------------------------- +// +// This header file defines a set of macros for checking the presence of +// important compiler and platform features. Such macros can be used to +// produce portable code by parameterizing compilation based on the presence or +// lack of a given feature. +// +// We define a "feature" as some interface we wish to program to: for example, +// a library function or system call. A value of `1` indicates support for +// that feature; any other value indicates the feature support is undefined. +// +// Example: +// +// Suppose a programmer wants to write a program that uses the 'mmap()' system +// call. The Abseil macro for that feature (`OTABSL_HAVE_MMAP`) allows you to +// selectively include the `mmap.h` header and bracket code using that feature +// in the macro: +// +// #include "absl/base/config.h" +// +// #ifdef OTABSL_HAVE_MMAP +// #include "sys/mman.h" +// #endif //OTABSL_HAVE_MMAP +// +// ... +// #ifdef OTABSL_HAVE_MMAP +// void *ptr = mmap(...); +// ... +// #endif // OTABSL_HAVE_MMAP + +#ifndef OTABSL_BASE_CONFIG_H_ +#define OTABSL_BASE_CONFIG_H_ + +// Included for the __GLIBC__ macro (or similar macros on other systems). +#include + +#ifdef __cplusplus +// Included for __GLIBCXX__, _LIBCPP_VERSION +#include +#endif // __cplusplus + +#if defined(__APPLE__) +// Included for TARGET_OS_IPHONE, __IPHONE_OS_VERSION_MIN_REQUIRED, +// __IPHONE_8_0. +#include +#include +#endif + +#include "options.h" +#include "policy_checks.h" + +// Helper macro to convert a CPP variable to a string literal. +#define OTABSL_INTERNAL_DO_TOKEN_STR(x) #x +#define OTABSL_INTERNAL_TOKEN_STR(x) OTABSL_INTERNAL_DO_TOKEN_STR(x) + +// ----------------------------------------------------------------------------- +// Abseil namespace annotations +// ----------------------------------------------------------------------------- + +// OTABSL_NAMESPACE_BEGIN/OTABSL_NAMESPACE_END +// +// An annotation placed at the beginning/end of each `namespace absl` scope. +// This is used to inject an inline namespace. +// +// The proper way to write Abseil code in the `absl` namespace is: +// +// namespace absl { +// OTABSL_NAMESPACE_BEGIN +// +// void Foo(); // absl::OTABSL_OPTION_NAMESPACE_NAME::Foo(). +// +// OTABSL_NAMESPACE_END +// } // namespace absl +// +// Users of Abseil should not use these macros, because users of Abseil should +// not write `namespace absl {` in their own code for any reason. (Abseil does +// not support forward declarations of its own types, nor does it support +// user-provided specialization of Abseil templates. Code that violates these +// rules may be broken without warning.) +#if !defined(OTABSL_OPTION_NAMESPACE_NAME) +#error options.h is misconfigured. +#endif + +// Check that OTABSL_OPTION_NAMESPACE_NAME is neither "head" nor "" +#if defined(__cplusplus) + +#define OTABSL_INTERNAL_INLINE_NAMESPACE_STR \ + OTABSL_INTERNAL_TOKEN_STR(OTABSL_OPTION_NAMESPACE_NAME) + +static_assert(OTABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != '\0', + "options.h misconfigured: OTABSL_OPTION_NAMESPACE_NAME must " + "not be empty."); +static_assert(OTABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || + OTABSL_INTERNAL_INLINE_NAMESPACE_STR[1] != 'e' || + OTABSL_INTERNAL_INLINE_NAMESPACE_STR[2] != 'a' || + OTABSL_INTERNAL_INLINE_NAMESPACE_STR[3] != 'd' || + OTABSL_INTERNAL_INLINE_NAMESPACE_STR[4] != '\0', + "options.h misconfigured: OTABSL_OPTION_NAMESPACE_NAME must " + "be changed to a new, unique identifier name."); + +#endif + + +#define OTABSL_NAMESPACE_BEGIN namespace OTABSL_OPTION_NAMESPACE_NAME { +#define OTABSL_NAMESPACE_END } + +// ----------------------------------------------------------------------------- +// Compiler Feature Checks +// ----------------------------------------------------------------------------- + +// OTABSL_HAVE_BUILTIN() +// +// Checks whether the compiler supports a Clang Feature Checking Macro, and if +// so, checks whether it supports the provided builtin function "x" where x +// is one of the functions noted in +// https://clang.llvm.org/docs/LanguageExtensions.html +// +// Note: Use this macro to avoid an extra level of #ifdef __has_builtin check. +// http://releases.llvm.org/3.3/tools/clang/docs/LanguageExtensions.html +#ifdef __has_builtin +#define OTABSL_HAVE_BUILTIN(x) __has_builtin(x) +#else +#define OTABSL_HAVE_BUILTIN(x) 0 +#endif + +#if defined(__is_identifier) +#define OTABSL_INTERNAL_HAS_KEYWORD(x) !(__is_identifier(x)) +#else +#define OTABSL_INTERNAL_HAS_KEYWORD(x) 0 +#endif + +// OTABSL_HAVE_TLS is defined to 1 when __thread should be supported. +// We assume __thread is supported on Linux when compiled with Clang or compiled +// against libstdc++ with _GLIBCXX_HAVE_TLS defined. +#ifdef OTABSL_HAVE_TLS +#error OTABSL_HAVE_TLS cannot be directly set +#elif defined(__linux__) && (defined(__clang__) || defined(_GLIBCXX_HAVE_TLS)) +#define OTABSL_HAVE_TLS 1 +#endif + +// OTABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE +// +// Checks whether `std::is_trivially_destructible` is supported. +// +// Notes: All supported compilers using libc++ support this feature, as does +// gcc >= 4.8.1 using libstdc++, and Visual Studio. +#ifdef OTABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE +#error OTABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE cannot be directly set +#elif defined(_LIBCPP_VERSION) || \ + (defined(__clang__) && __clang_major__ >= 15) || \ + (!defined(__clang__) && defined(__GNUC__) && defined(__GLIBCXX__) && \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) || \ + defined(_MSC_VER) +#define OTABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 1 +#endif + +// OTABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE +// +// Checks whether `std::is_trivially_default_constructible` and +// `std::is_trivially_copy_constructible` are supported. + +// OTABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE +// +// Checks whether `std::is_trivially_copy_assignable` is supported. + +// Notes: Clang with libc++ supports these features, as does gcc >= 5.1 with +// either libc++ or libstdc++, and Visual Studio (but not NVCC). +#if defined(OTABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) +#error OTABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE cannot be directly set +#elif defined(OTABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE) +#error OTABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE cannot directly set +#elif (defined(__clang__) && defined(_LIBCPP_VERSION)) || \ + (defined(__clang__) && __clang_major__ >= 15) || \ + (!defined(__clang__) && defined(__GNUC__) && \ + (__GNUC__ > 7 || (__GNUC__ == 7 && __GNUC_MINOR__ >= 4)) && \ + (defined(_LIBCPP_VERSION) || defined(__GLIBCXX__))) || \ + (defined(_MSC_VER) && !defined(__NVCC__)) +#define OTABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 1 +#define OTABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 1 +#endif + +// OTABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE +// +// Checks whether `std::is_trivially_copyable` is supported. +// +// Notes: Clang 15+ with libc++ supports these features, GCC hasn't been tested. +#if defined(OTABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE) +#error OTABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE cannot be directly set +#elif defined(__clang__) && (__clang_major__ >= 15) +#define OTABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE 1 +#endif + +// OTABSL_HAVE_SOURCE_LOCATION_CURRENT +// +// Indicates whether `absl::OTABSL_OPTION_NAMESPACE_NAME::SourceLocation::current()` will return useful +// information in some contexts. +#ifndef OTABSL_HAVE_SOURCE_LOCATION_CURRENT +#if OTABSL_INTERNAL_HAS_KEYWORD(__builtin_LINE) && \ + OTABSL_INTERNAL_HAS_KEYWORD(__builtin_FILE) +#define OTABSL_HAVE_SOURCE_LOCATION_CURRENT 1 +#endif +#endif + +// OTABSL_HAVE_THREAD_LOCAL +// +// Checks whether C++11's `thread_local` storage duration specifier is +// supported. +#ifdef OTABSL_HAVE_THREAD_LOCAL +#error OTABSL_HAVE_THREAD_LOCAL cannot be directly set +#elif defined(__APPLE__) +// Notes: +// * Xcode's clang did not support `thread_local` until version 8, and +// even then not for all iOS < 9.0. +// * Xcode 9.3 started disallowing `thread_local` for 32-bit iOS simulator +// targeting iOS 9.x. +// * Xcode 10 moves the deployment target check for iOS < 9.0 to link time +// making __has_feature unreliable there. +// +// Otherwise, `__has_feature` is only supported by Clang so it has be inside +// `defined(__APPLE__)` check. +#if __has_feature(cxx_thread_local) && \ + !(TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0) +#define OTABSL_HAVE_THREAD_LOCAL 1 +#endif +#else // !defined(__APPLE__) +#define OTABSL_HAVE_THREAD_LOCAL 1 +#endif + +// There are platforms for which TLS should not be used even though the compiler +// makes it seem like it's supported (Android NDK < r12b for example). +// This is primarily because of linker problems and toolchain misconfiguration: +// Abseil does not intend to support this indefinitely. Currently, the newest +// toolchain that we intend to support that requires this behavior is the +// r11 NDK - allowing for a 5 year support window on that means this option +// is likely to be removed around June of 2021. +// TLS isn't supported until NDK r12b per +// https://developer.android.com/ndk/downloads/revision_history.html +// Since NDK r16, `__NDK_MAJOR__` and `__NDK_MINOR__` are defined in +// . For NDK < r16, users should define these macros, +// e.g. `-D__NDK_MAJOR__=11 -D__NKD_MINOR__=0` for NDK r11. +#if defined(__ANDROID__) && defined(__clang__) +#if __has_include() +#include +#endif // __has_include() +#if defined(__ANDROID__) && defined(__clang__) && defined(__NDK_MAJOR__) && \ + defined(__NDK_MINOR__) && \ + ((__NDK_MAJOR__ < 12) || ((__NDK_MAJOR__ == 12) && (__NDK_MINOR__ < 1))) +#undef OTABSL_HAVE_TLS +#undef OTABSL_HAVE_THREAD_LOCAL +#endif +#endif // defined(__ANDROID__) && defined(__clang__) + +// Emscripten doesn't yet support `thread_local` or `__thread`. +// https://github.com/emscripten-core/emscripten/issues/3502 +#if defined(__EMSCRIPTEN__) +#undef OTABSL_HAVE_TLS +#undef OTABSL_HAVE_THREAD_LOCAL +#endif // defined(__EMSCRIPTEN__) + +// OTABSL_HAVE_INTRINSIC_INT128 +// +// Checks whether the __int128 compiler extension for a 128-bit integral type is +// supported. +// +// Note: __SIZEOF_INT128__ is defined by Clang and GCC when __int128 is +// supported, but we avoid using it in certain cases: +// * On Clang: +// * Building using Clang for Windows, where the Clang runtime library has +// 128-bit support only on LP64 architectures, but Windows is LLP64. +// * On Nvidia's nvcc: +// * nvcc also defines __GNUC__ and __SIZEOF_INT128__, but not all versions +// actually support __int128. +#ifdef OTABSL_HAVE_INTRINSIC_INT128 +#error OTABSL_HAVE_INTRINSIC_INT128 cannot be directly set +#elif defined(__SIZEOF_INT128__) +#if (defined(__clang__) && !defined(_WIN32)) || \ + (defined(__CUDACC__) && __CUDACC_VER_MAJOR__ >= 9) || \ + (defined(__GNUC__) && !defined(__clang__) && !defined(__CUDACC__)) +#define OTABSL_HAVE_INTRINSIC_INT128 1 +#elif defined(__CUDACC__) +// __CUDACC_VER__ is a full version number before CUDA 9, and is defined to a +// string explaining that it has been removed starting with CUDA 9. We use +// nested #ifs because there is no short-circuiting in the preprocessor. +// NOTE: `__CUDACC__` could be undefined while `__CUDACC_VER__` is defined. +#if __CUDACC_VER__ >= 70000 +#define OTABSL_HAVE_INTRINSIC_INT128 1 +#endif // __CUDACC_VER__ >= 70000 +#endif // defined(__CUDACC__) +#endif // OTABSL_HAVE_INTRINSIC_INT128 + +// OTABSL_HAVE_EXCEPTIONS +// +// Checks whether the compiler both supports and enables exceptions. Many +// compilers support a "no exceptions" mode that disables exceptions. +// +// Generally, when OTABSL_HAVE_EXCEPTIONS is not defined: +// +// * Code using `throw` and `try` may not compile. +// * The `noexcept` specifier will still compile and behave as normal. +// * The `noexcept` operator may still return `false`. +// +// For further details, consult the compiler's documentation. +#ifdef OTABSL_HAVE_EXCEPTIONS +#error OTABSL_HAVE_EXCEPTIONS cannot be directly set. + +#elif defined(__clang__) + +#if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 6) +// Clang >= 3.6 +#if __has_feature(cxx_exceptions) +#define OTABSL_HAVE_EXCEPTIONS 1 +#endif // __has_feature(cxx_exceptions) +#else +// Clang < 3.6 +// http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro +#if defined(__EXCEPTIONS) && __has_feature(cxx_exceptions) +#define OTABSL_HAVE_EXCEPTIONS 1 +#endif // defined(__EXCEPTIONS) && __has_feature(cxx_exceptions) +#endif // __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 6) + +// Handle remaining special cases and default to exceptions being supported. +#elif !(defined(__GNUC__) && (__GNUC__ < 5) && !defined(__EXCEPTIONS)) && \ + !(defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__cpp_exceptions)) && \ + !(defined(_MSC_VER) && !defined(_CPPUNWIND)) +#define OTABSL_HAVE_EXCEPTIONS 1 +#endif + +// ----------------------------------------------------------------------------- +// Platform Feature Checks +// ----------------------------------------------------------------------------- + +// Currently supported operating systems and associated preprocessor +// symbols: +// +// Linux and Linux-derived __linux__ +// Android __ANDROID__ (implies __linux__) +// Linux (non-Android) __linux__ && !__ANDROID__ +// Darwin (macOS and iOS) __APPLE__ +// Akaros (http://akaros.org) __ros__ +// Windows _WIN32 +// NaCL __native_client__ +// AsmJS __asmjs__ +// WebAssembly __wasm__ +// Fuchsia __Fuchsia__ +// +// Note that since Android defines both __ANDROID__ and __linux__, one +// may probe for either Linux or Android by simply testing for __linux__. + +// OTABSL_HAVE_MMAP +// +// Checks whether the platform has an mmap(2) implementation as defined in +// POSIX.1-2001. +#ifdef OTABSL_HAVE_MMAP +#error OTABSL_HAVE_MMAP cannot be directly set +#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ + defined(__ros__) || defined(__native_client__) || defined(__asmjs__) || \ + defined(__wasm__) || defined(__Fuchsia__) || defined(__sun) || \ + defined(__ASYLO__) +#define OTABSL_HAVE_MMAP 1 +#endif + +// OTABSL_HAVE_PTHREAD_GETSCHEDPARAM +// +// Checks whether the platform implements the pthread_(get|set)schedparam(3) +// functions as defined in POSIX.1-2001. +#ifdef OTABSL_HAVE_PTHREAD_GETSCHEDPARAM +#error OTABSL_HAVE_PTHREAD_GETSCHEDPARAM cannot be directly set +#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ + defined(__ros__) +#define OTABSL_HAVE_PTHREAD_GETSCHEDPARAM 1 +#endif + +// OTABSL_HAVE_SCHED_YIELD +// +// Checks whether the platform implements sched_yield(2) as defined in +// POSIX.1-2001. +#ifdef OTABSL_HAVE_SCHED_YIELD +#error OTABSL_HAVE_SCHED_YIELD cannot be directly set +#elif defined(__linux__) || defined(__ros__) || defined(__native_client__) +#define OTABSL_HAVE_SCHED_YIELD 1 +#endif + +// OTABSL_HAVE_SEMAPHORE_H +// +// Checks whether the platform supports the header and sem_init(3) +// family of functions as standardized in POSIX.1-2001. +// +// Note: While Apple provides for both iOS and macOS, it is +// explicitly deprecated and will cause build failures if enabled for those +// platforms. We side-step the issue by not defining it here for Apple +// platforms. +#ifdef OTABSL_HAVE_SEMAPHORE_H +#error OTABSL_HAVE_SEMAPHORE_H cannot be directly set +#elif defined(__linux__) || defined(__ros__) +#define OTABSL_HAVE_SEMAPHORE_H 1 +#endif + +// OTABSL_HAVE_ALARM +// +// Checks whether the platform supports the header and alarm(2) +// function as standardized in POSIX.1-2001. +#ifdef OTABSL_HAVE_ALARM +#error OTABSL_HAVE_ALARM cannot be directly set +#elif defined(__GOOGLE_GRTE_VERSION__) +// feature tests for Google's GRTE +#define OTABSL_HAVE_ALARM 1 +#elif defined(__GLIBC__) +// feature test for glibc +#define OTABSL_HAVE_ALARM 1 +#elif defined(_MSC_VER) +// feature tests for Microsoft's library +#elif defined(__MINGW32__) +// mingw32 doesn't provide alarm(2): +// https://osdn.net/projects/mingw/scm/git/mingw-org-wsl/blobs/5.2-trunk/mingwrt/include/unistd.h +// mingw-w64 provides a no-op implementation: +// https://sourceforge.net/p/mingw-w64/mingw-w64/ci/master/tree/mingw-w64-crt/misc/alarm.c +#elif defined(__EMSCRIPTEN__) +// emscripten doesn't support signals +#elif defined(__Fuchsia__) +// Signals don't exist on fuchsia. +#elif defined(__native_client__) +#else +// other standard libraries +#define OTABSL_HAVE_ALARM 1 +#endif + +// OTABSL_IS_LITTLE_ENDIAN +// OTABSL_IS_BIG_ENDIAN +// +// Checks the endianness of the platform. +// +// Notes: uses the built in endian macros provided by GCC (since 4.6) and +// Clang (since 3.2); see +// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html. +// Otherwise, if _WIN32, assume little endian. Otherwise, bail with an error. +#if defined(OTABSL_IS_BIG_ENDIAN) +#error "OTABSL_IS_BIG_ENDIAN cannot be directly set." +#endif +#if defined(OTABSL_IS_LITTLE_ENDIAN) +#error "OTABSL_IS_LITTLE_ENDIAN cannot be directly set." +#endif + +#if (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ + __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#define OTABSL_IS_LITTLE_ENDIAN 1 +#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ + __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define OTABSL_IS_BIG_ENDIAN 1 +#elif defined(_WIN32) +#define OTABSL_IS_LITTLE_ENDIAN 1 +#else +#error "absl endian detection needs to be set up for your compiler" +#endif + +// macOS 10.13 and iOS 10.11 don't let you use , , or +// even though the headers exist and are publicly noted to work. See +// https://github.com/abseil/abseil-cpp/issues/207 and +// https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes +// libc++ spells out the availability requirements in the file +// llvm-project/libcxx/include/__config via the #define +// _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS. +#if defined(__APPLE__) && defined(_LIBCPP_VERSION) && \ + ((defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \ + __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101400) || \ + (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \ + __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 120000) || \ + (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && \ + __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 120000) || \ + (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && \ + __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 50000)) +#define OTABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE 1 +#else +#define OTABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE 0 +#endif + +// OTABSL_HAVE_STD_ANY +// +// Checks whether C++17 std::any is available by checking whether exists. +#ifdef OTABSL_HAVE_STD_ANY +#error "OTABSL_HAVE_STD_ANY cannot be directly set." +#endif + +#ifdef __has_include +#if __has_include() && __cplusplus >= 201703L && \ + !OTABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE +#define OTABSL_HAVE_STD_ANY 1 +#endif +#endif + +// OTABSL_HAVE_STD_OPTIONAL +// +// Checks whether C++17 std::optional is available. +#ifdef OTABSL_HAVE_STD_OPTIONAL +#error "OTABSL_HAVE_STD_OPTIONAL cannot be directly set." +#endif + +#ifdef __has_include +#if __has_include() && __cplusplus >= 201703L && \ + !OTABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE +#define OTABSL_HAVE_STD_OPTIONAL 1 +#endif +#endif + +// OTABSL_HAVE_STD_VARIANT +// +// Checks whether C++17 std::variant is available. +#ifdef OTABSL_HAVE_STD_VARIANT +#error "OTABSL_HAVE_STD_VARIANT cannot be directly set." +#endif + +#ifdef __has_include +#if __has_include() && __cplusplus >= 201703L && \ + !OTABSL_INTERNAL_APPLE_CXX17_TYPES_UNAVAILABLE +#define OTABSL_HAVE_STD_VARIANT 1 +#endif +#endif + +// OTABSL_HAVE_STD_STRING_VIEW +// +// Checks whether C++17 std::string_view is available. +#ifdef OTABSL_HAVE_STD_STRING_VIEW +#error "OTABSL_HAVE_STD_STRING_VIEW cannot be directly set." +#endif + +#ifdef __has_include +#if __has_include() && __cplusplus >= 201703L +#define OTABSL_HAVE_STD_STRING_VIEW 1 +#endif +#endif + +// For MSVC, `__has_include` is supported in VS 2017 15.3, which is later than +// the support for , , , . So we use +// _MSC_VER to check whether we have VS 2017 RTM (when , , +// , is implemented) or higher. Also, `__cplusplus` is +// not correctly set by MSVC, so we use `_MSVC_LANG` to check the language +// version. +// TODO(zhangxy): fix tests before enabling aliasing for `std::any`. +#if defined(_MSC_VER) && _MSC_VER >= 1910 && \ + ((defined(_MSVC_LANG) && _MSVC_LANG > 201402) || __cplusplus > 201402) +// #define OTABSL_HAVE_STD_ANY 1 +#define OTABSL_HAVE_STD_OPTIONAL 1 +#define OTABSL_HAVE_STD_VARIANT 1 +#define OTABSL_HAVE_STD_STRING_VIEW 1 +#endif + +// OTABSL_USES_STD_ANY +// +// Indicates whether absl::OTABSL_OPTION_NAMESPACE_NAME::any is an alias for std::any. +#if !defined(OTABSL_OPTION_USE_STD_ANY) +#error options.h is misconfigured. +#elif OTABSL_OPTION_USE_STD_ANY == 0 || \ + (OTABSL_OPTION_USE_STD_ANY == 2 && !defined(OTABSL_HAVE_STD_ANY)) +#undef OTABSL_USES_STD_ANY +#elif OTABSL_OPTION_USE_STD_ANY == 1 || \ + (OTABSL_OPTION_USE_STD_ANY == 2 && defined(OTABSL_HAVE_STD_ANY)) +#define OTABSL_USES_STD_ANY 1 +#else +#error options.h is misconfigured. +#endif + +// OTABSL_USES_STD_OPTIONAL +// +// Indicates whether absl::OTABSL_OPTION_NAMESPACE_NAME::optional is an alias for std::optional. +#if !defined(OTABSL_OPTION_USE_STD_OPTIONAL) +#error options.h is misconfigured. +#elif OTABSL_OPTION_USE_STD_OPTIONAL == 0 || \ + (OTABSL_OPTION_USE_STD_OPTIONAL == 2 && !defined(OTABSL_HAVE_STD_OPTIONAL)) +#undef OTABSL_USES_STD_OPTIONAL +#elif OTABSL_OPTION_USE_STD_OPTIONAL == 1 || \ + (OTABSL_OPTION_USE_STD_OPTIONAL == 2 && defined(OTABSL_HAVE_STD_OPTIONAL)) +#define OTABSL_USES_STD_OPTIONAL 1 +#else +#error options.h is misconfigured. +#endif + +// OTABSL_USES_STD_VARIANT +// +// Indicates whether absl::OTABSL_OPTION_NAMESPACE_NAME::variant is an alias for std::variant. +#if !defined(OTABSL_OPTION_USE_STD_VARIANT) +#error options.h is misconfigured. +#elif OTABSL_OPTION_USE_STD_VARIANT == 0 || \ + (OTABSL_OPTION_USE_STD_VARIANT == 2 && !defined(OTABSL_HAVE_STD_VARIANT)) +#undef OTABSL_USES_STD_VARIANT +#elif OTABSL_OPTION_USE_STD_VARIANT == 1 || \ + (OTABSL_OPTION_USE_STD_VARIANT == 2 && defined(OTABSL_HAVE_STD_VARIANT)) +#define OTABSL_USES_STD_VARIANT 1 +#else +#error options.h is misconfigured. +#endif + +// OTABSL_USES_STD_STRING_VIEW +// +// Indicates whether absl::OTABSL_OPTION_NAMESPACE_NAME::string_view is an alias for std::string_view. +#if !defined(OTABSL_OPTION_USE_STD_STRING_VIEW) +#error options.h is misconfigured. +#elif OTABSL_OPTION_USE_STD_STRING_VIEW == 0 || \ + (OTABSL_OPTION_USE_STD_STRING_VIEW == 2 && \ + !defined(OTABSL_HAVE_STD_STRING_VIEW)) +#undef OTABSL_USES_STD_STRING_VIEW +#elif OTABSL_OPTION_USE_STD_STRING_VIEW == 1 || \ + (OTABSL_OPTION_USE_STD_STRING_VIEW == 2 && \ + defined(OTABSL_HAVE_STD_STRING_VIEW)) +#define OTABSL_USES_STD_STRING_VIEW 1 +#else +#error options.h is misconfigured. +#endif + +// In debug mode, MSVC 2017's std::variant throws a EXCEPTION_ACCESS_VIOLATION +// SEH exception from emplace for variant when constructing the +// struct can throw. This defeats some of variant_test and +// variant_exception_safety_test. +#if defined(_MSC_VER) && _MSC_VER >= 1700 && defined(_DEBUG) +#define OTABSL_INTERNAL_MSVC_2017_DBG_MODE +#endif + +// OTABSL_INTERNAL_MANGLED_NS +// OTABSL_INTERNAL_MANGLED_BACKREFERENCE +// +// Internal macros for building up mangled names in our internal fork of CCTZ. +// This implementation detail is only needed and provided for the MSVC build. +// +// These macros both expand to string literals. OTABSL_INTERNAL_MANGLED_NS is +// the mangled spelling of the `absl` namespace, and +// OTABSL_INTERNAL_MANGLED_BACKREFERENCE is a back-reference integer representing +// the proper count to skip past the CCTZ fork namespace names. (This number +// is one larger when there is an inline namespace name to skip.) +#if defined(_MSC_VER) +#define OTABSL_INTERNAL_MANGLED_NS \ + OTABSL_INTERNAL_TOKEN_STR(OTABSL_OPTION_NAMESPACE_NAME) "@absl" +#define OTABSL_INTERNAL_MANGLED_BACKREFERENCE "6" +#endif + +#undef OTABSL_INTERNAL_HAS_KEYWORD + +// OTABSL_DLL +// +// When building Abseil as a DLL, this macro expands to `__declspec(dllexport)` +// so we can annotate symbols appropriately as being exported. When used in +// headers consuming a DLL, this macro expands to `__declspec(dllimport)` so +// that consumers know the symbol is defined inside the DLL. In all other cases, +// the macro expands to nothing. +#if defined(_MSC_VER) +#if defined(OTABSL_BUILD_DLL) +#define OTABSL_DLL __declspec(dllexport) +#elif 1 +#define OTABSL_DLL __declspec(dllimport) +#else +#define OTABSL_DLL +#endif +#else +#define OTABSL_DLL +#endif // defined(_MSC_VER) + +#endif // OTABSL_BASE_CONFIG_H_ diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/internal/identity.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/internal/identity.h new file mode 100644 index 000000000..4afba3179 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/internal/identity.h @@ -0,0 +1,37 @@ +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef OTABSL_BASE_INTERNAL_IDENTITY_H_ +#define OTABSL_BASE_INTERNAL_IDENTITY_H_ + +#include "../config.h" + +namespace absl { +OTABSL_NAMESPACE_BEGIN +namespace internal { + +template +struct identity { + typedef T type; +}; + +template +using identity_t = typename identity::type; + +} // namespace internal +OTABSL_NAMESPACE_END +} // namespace absl + +#endif // OTABSL_BASE_INTERNAL_IDENTITY_H_ diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/internal/inline_variable.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/internal/inline_variable.h new file mode 100644 index 000000000..dd66e9f22 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/internal/inline_variable.h @@ -0,0 +1,107 @@ +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OTABSL_BASE_INTERNAL_INLINE_VARIABLE_EMULATION_H_ +#define OTABSL_BASE_INTERNAL_INLINE_VARIABLE_EMULATION_H_ + +#include + +#include "identity.h" + +// File: +// This file define a macro that allows the creation of or emulation of C++17 +// inline variables based on whether or not the feature is supported. + +//////////////////////////////////////////////////////////////////////////////// +// Macro: OTABSL_INTERNAL_INLINE_CONSTEXPR(type, name, init) +// +// Description: +// Expands to the equivalent of an inline constexpr instance of the specified +// `type` and `name`, initialized to the value `init`. If the compiler being +// used is detected as supporting actual inline variables as a language +// feature, then the macro expands to an actual inline variable definition. +// +// Requires: +// `type` is a type that is usable in an extern variable declaration. +// +// Requires: `name` is a valid identifier +// +// Requires: +// `init` is an expression that can be used in the following definition: +// constexpr type name = init; +// +// Usage: +// +// // Equivalent to: `inline constexpr size_t variant_npos = -1;` +// OTABSL_INTERNAL_INLINE_CONSTEXPR(size_t, variant_npos, -1); +// +// Differences in implementation: +// For a direct, language-level inline variable, decltype(name) will be the +// type that was specified along with const qualification, whereas for +// emulated inline variables, decltype(name) may be different (in practice +// it will likely be a reference type). +//////////////////////////////////////////////////////////////////////////////// + +#ifdef __cpp_inline_variables + +// Clang's -Wmissing-variable-declarations option erroneously warned that +// inline constexpr objects need to be pre-declared. This has now been fixed, +// but we will need to support this workaround for people building with older +// versions of clang. +// +// Bug: https://bugs.llvm.org/show_bug.cgi?id=35862 +// +// Note: +// identity_t is used here so that the const and name are in the +// appropriate place for pointer types, reference types, function pointer +// types, etc.. +#if defined(__clang__) +#define OTABSL_INTERNAL_EXTERN_DECL(type, name) \ + extern const ::absl::OTABSL_OPTION_NAMESPACE_NAME::internal::identity_t name; +#else // Otherwise, just define the macro to do nothing. +#define OTABSL_INTERNAL_EXTERN_DECL(type, name) +#endif // defined(__clang__) + +// See above comment at top of file for details. +#define OTABSL_INTERNAL_INLINE_CONSTEXPR(type, name, init) \ + OTABSL_INTERNAL_EXTERN_DECL(type, name) \ + inline constexpr ::absl::OTABSL_OPTION_NAMESPACE_NAME::internal::identity_t name = init + +#else + +// See above comment at top of file for details. +// +// Note: +// identity_t is used here so that the const and name are in the +// appropriate place for pointer types, reference types, function pointer +// types, etc.. +#define OTABSL_INTERNAL_INLINE_CONSTEXPR(var_type, name, init) \ + template \ + struct AbslInternalInlineVariableHolder##name { \ + static constexpr ::absl::OTABSL_OPTION_NAMESPACE_NAME::internal::identity_t kInstance = init; \ + }; \ + \ + template \ + constexpr ::absl::OTABSL_OPTION_NAMESPACE_NAME::internal::identity_t \ + AbslInternalInlineVariableHolder##name::kInstance; \ + \ + static constexpr const ::absl::OTABSL_OPTION_NAMESPACE_NAME::internal::identity_t& \ + name = /* NOLINT */ \ + AbslInternalInlineVariableHolder##name<>::kInstance; \ + static_assert(sizeof(void (*)(decltype(name))) != 0, \ + "Silence unused variable warnings.") + +#endif // __cpp_inline_variables + +#endif // OTABSL_BASE_INTERNAL_INLINE_VARIABLE_EMULATION_H_ diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/internal/invoke.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/internal/invoke.h new file mode 100644 index 000000000..c37f43cfc --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/internal/invoke.h @@ -0,0 +1,188 @@ +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// absl::OTABSL_OPTION_NAMESPACE_NAME::base_internal::Invoke(f, args...) is an implementation of +// INVOKE(f, args...) from section [func.require] of the C++ standard. +// +// [func.require] +// Define INVOKE (f, t1, t2, ..., tN) as follows: +// 1. (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T +// and t1 is an object of type T or a reference to an object of type T or a +// reference to an object of a type derived from T; +// 2. ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a +// class T and t1 is not one of the types described in the previous item; +// 3. t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is +// an object of type T or a reference to an object of type T or a reference +// to an object of a type derived from T; +// 4. (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 +// is not one of the types described in the previous item; +// 5. f(t1, t2, ..., tN) in all other cases. +// +// The implementation is SFINAE-friendly: substitution failure within Invoke() +// isn't an error. + +#ifndef OTABSL_BASE_INTERNAL_INVOKE_H_ +#define OTABSL_BASE_INTERNAL_INVOKE_H_ + +#include +#include +#include + +#include "../../meta/type_traits.h" + +// The following code is internal implementation detail. See the comment at the +// top of this file for the API documentation. + +namespace absl { +OTABSL_NAMESPACE_BEGIN +namespace base_internal { + +// The five classes below each implement one of the clauses from the definition +// of INVOKE. The inner class template Accept checks whether the +// clause is applicable; static function template Invoke(f, args...) does the +// invocation. +// +// By separating the clause selection logic from invocation we make sure that +// Invoke() does exactly what the standard says. + +template +struct StrippedAccept { + template + struct Accept : Derived::template AcceptImpl::type>::type...> {}; +}; + +// (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T +// and t1 is an object of type T or a reference to an object of type T or a +// reference to an object of a type derived from T. +struct MemFunAndRef : StrippedAccept { + template + struct AcceptImpl : std::false_type {}; + + template + struct AcceptImpl + : std::integral_constant::value && + absl::OTABSL_OPTION_NAMESPACE_NAME::is_function::value> { + }; + + template + static decltype((std::declval().* + std::declval())(std::declval()...)) + Invoke(MemFun&& mem_fun, Obj&& obj, Args&&... args) { + return (std::forward(obj).* + std::forward(mem_fun))(std::forward(args)...); + } +}; + +// ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a +// class T and t1 is not one of the types described in the previous item. +struct MemFunAndPtr : StrippedAccept { + template + struct AcceptImpl : std::false_type {}; + + template + struct AcceptImpl + : std::integral_constant::value && + absl::OTABSL_OPTION_NAMESPACE_NAME::is_function::value> { + }; + + template + static decltype(((*std::declval()).* + std::declval())(std::declval()...)) + Invoke(MemFun&& mem_fun, Ptr&& ptr, Args&&... args) { + return ((*std::forward(ptr)).* + std::forward(mem_fun))(std::forward(args)...); + } +}; + +// t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is +// an object of type T or a reference to an object of type T or a reference +// to an object of a type derived from T. +struct DataMemAndRef : StrippedAccept { + template + struct AcceptImpl : std::false_type {}; + + template + struct AcceptImpl + : std::integral_constant::value && + !absl::OTABSL_OPTION_NAMESPACE_NAME::is_function::value> {}; + + template + static decltype(std::declval().*std::declval()) Invoke( + DataMem&& data_mem, Ref&& ref) { + return std::forward(ref).*std::forward(data_mem); + } +}; + +// (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 +// is not one of the types described in the previous item. +struct DataMemAndPtr : StrippedAccept { + template + struct AcceptImpl : std::false_type {}; + + template + struct AcceptImpl + : std::integral_constant::value && + !absl::OTABSL_OPTION_NAMESPACE_NAME::is_function::value> {}; + + template + static decltype((*std::declval()).*std::declval()) Invoke( + DataMem&& data_mem, Ptr&& ptr) { + return (*std::forward(ptr)).*std::forward(data_mem); + } +}; + +// f(t1, t2, ..., tN) in all other cases. +struct Callable { + // Callable doesn't have Accept because it's the last clause that gets picked + // when none of the previous clauses are applicable. + template + static decltype(std::declval()(std::declval()...)) Invoke( + F&& f, Args&&... args) { + return std::forward(f)(std::forward(args)...); + } +}; + +// Resolves to the first matching clause. +template +struct Invoker { + typedef typename std::conditional< + MemFunAndRef::Accept::value, MemFunAndRef, + typename std::conditional< + MemFunAndPtr::Accept::value, MemFunAndPtr, + typename std::conditional< + DataMemAndRef::Accept::value, DataMemAndRef, + typename std::conditional::value, + DataMemAndPtr, Callable>::type>::type>:: + type>::type type; +}; + +// The result type of Invoke. +template +using InvokeT = decltype(Invoker::type::Invoke( + std::declval(), std::declval()...)); + +// Invoke(f, args...) is an implementation of INVOKE(f, args...) from section +// [func.require] of the C++ standard. +template +InvokeT Invoke(F&& f, Args&&... args) { + return Invoker::type::Invoke(std::forward(f), + std::forward(args)...); +} + +} // namespace base_internal +OTABSL_NAMESPACE_END +} // namespace absl + +#endif // OTABSL_BASE_INTERNAL_INVOKE_H_ diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/macros.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/macros.h new file mode 100644 index 000000000..707c375ed --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/macros.h @@ -0,0 +1,220 @@ +// +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ----------------------------------------------------------------------------- +// File: macros.h +// ----------------------------------------------------------------------------- +// +// This header file defines the set of language macros used within Abseil code. +// For the set of macros used to determine supported compilers and platforms, +// see absl/base/config.h instead. +// +// This code is compiled directly on many platforms, including client +// platforms like Windows, Mac, and embedded systems. Before making +// any changes here, make sure that you're not breaking any platforms. + +#ifndef OTABSL_BASE_MACROS_H_ +#define OTABSL_BASE_MACROS_H_ + +#include +#include + +#include "attributes.h" +#include "optimization.h" +#include "port.h" + +// OTABSL_ARRAYSIZE() +// +// Returns the number of elements in an array as a compile-time constant, which +// can be used in defining new arrays. If you use this macro on a pointer by +// mistake, you will get a compile-time error. +#define OTABSL_ARRAYSIZE(array) \ + (sizeof(::absl::OTABSL_OPTION_NAMESPACE_NAME::macros_internal::ArraySizeHelper(array))) + +namespace absl { +OTABSL_NAMESPACE_BEGIN +namespace macros_internal { +// Note: this internal template function declaration is used by OTABSL_ARRAYSIZE. +// The function doesn't need a definition, as we only use its type. +template +auto ArraySizeHelper(const T (&array)[N]) -> char (&)[N]; +} // namespace macros_internal +OTABSL_NAMESPACE_END +} // namespace absl + +// kLinkerInitialized +// +// An enum used only as a constructor argument to indicate that a variable has +// static storage duration, and that the constructor should do nothing to its +// state. Use of this macro indicates to the reader that it is legal to +// declare a static instance of the class, provided the constructor is given +// the absl::OTABSL_OPTION_NAMESPACE_NAME::base_internal::kLinkerInitialized argument. +// +// Normally, it is unsafe to declare a static variable that has a constructor or +// a destructor because invocation order is undefined. However, if the type can +// be zero-initialized (which the loader does for static variables) into a valid +// state and the type's destructor does not affect storage, then a constructor +// for static initialization can be declared. +// +// Example: +// // Declaration +// explicit MyClass(absl::OTABSL_OPTION_NAMESPACE_NAME::base_internal:LinkerInitialized x) {} +// +// // Invocation +// static MyClass my_global(absl::OTABSL_OPTION_NAMESPACE_NAME::base_internal::kLinkerInitialized); +namespace absl { +OTABSL_NAMESPACE_BEGIN +namespace base_internal { +enum LinkerInitialized { + kLinkerInitialized = 0, +}; +} // namespace base_internal +OTABSL_NAMESPACE_END +} // namespace absl + +// OTABSL_FALLTHROUGH_INTENDED +// +// Annotates implicit fall-through between switch labels, allowing a case to +// indicate intentional fallthrough and turn off warnings about any lack of a +// `break` statement. The OTABSL_FALLTHROUGH_INTENDED macro should be followed by +// a semicolon and can be used in most places where `break` can, provided that +// no statements exist between it and the next switch label. +// +// Example: +// +// switch (x) { +// case 40: +// case 41: +// if (truth_is_out_there) { +// ++x; +// OTABSL_FALLTHROUGH_INTENDED; // Use instead of/along with annotations +// // in comments +// } else { +// return x; +// } +// case 42: +// ... +// +// Notes: when compiled with clang in C++11 mode, the OTABSL_FALLTHROUGH_INTENDED +// macro is expanded to the [[clang::fallthrough]] attribute, which is analysed +// when performing switch labels fall-through diagnostic +// (`-Wimplicit-fallthrough`). See clang documentation on language extensions +// for details: +// https://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough +// +// When used with unsupported compilers, the OTABSL_FALLTHROUGH_INTENDED macro +// has no effect on diagnostics. In any case this macro has no effect on runtime +// behavior and performance of code. +#ifdef OTABSL_FALLTHROUGH_INTENDED +#error "OTABSL_FALLTHROUGH_INTENDED should not be defined." +#endif + +// TODO(zhangxy): Use c++17 standard [[fallthrough]] macro, when supported. +#if defined(__clang__) && defined(__has_warning) +#if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough") +#define OTABSL_FALLTHROUGH_INTENDED [[clang::fallthrough]] +#endif +#elif defined(__GNUC__) && __GNUC__ >= 7 +#define OTABSL_FALLTHROUGH_INTENDED [[gnu::fallthrough]] +#endif + +#ifndef OTABSL_FALLTHROUGH_INTENDED +#define OTABSL_FALLTHROUGH_INTENDED \ + do { \ + } while (0) +#endif + +// OTABSL_DEPRECATED() +// +// Marks a deprecated class, struct, enum, function, method and variable +// declarations. The macro argument is used as a custom diagnostic message (e.g. +// suggestion of a better alternative). +// +// Examples: +// +// class OTABSL_DEPRECATED("Use Bar instead") Foo {...}; +// +// OTABSL_DEPRECATED("Use Baz() instead") void Bar() {...} +// +// template +// OTABSL_DEPRECATED("Use DoThat() instead") +// void DoThis(); +// +// Every usage of a deprecated entity will trigger a warning when compiled with +// clang's `-Wdeprecated-declarations` option. This option is turned off by +// default, but the warnings will be reported by clang-tidy. +#if defined(__clang__) && __cplusplus >= 201103L +#define OTABSL_DEPRECATED(message) __attribute__((deprecated(message))) +#endif + +#ifndef OTABSL_DEPRECATED +#define OTABSL_DEPRECATED(message) +#endif + +// OTABSL_BAD_CALL_IF() +// +// Used on a function overload to trap bad calls: any call that matches the +// overload will cause a compile-time error. This macro uses a clang-specific +// "enable_if" attribute, as described at +// https://clang.llvm.org/docs/AttributeReference.html#enable-if +// +// Overloads which use this macro should be bracketed by +// `#ifdef OTABSL_BAD_CALL_IF`. +// +// Example: +// +// int isdigit(int c); +// #ifdef OTABSL_BAD_CALL_IF +// int isdigit(int c) +// OTABSL_BAD_CALL_IF(c <= -1 || c > 255, +// "'c' must have the value of an unsigned char or EOF"); +// #endif // OTABSL_BAD_CALL_IF +#if OTABSL_HAVE_ATTRIBUTE(enable_if) +#define OTABSL_BAD_CALL_IF(expr, msg) \ + __attribute__((enable_if(expr, "Bad call trap"), unavailable(msg))) +#endif + +// OTABSL_ASSERT() +// +// In C++11, `assert` can't be used portably within constexpr functions. +// OTABSL_ASSERT functions as a runtime assert but works in C++11 constexpr +// functions. Example: +// +// constexpr double Divide(double a, double b) { +// return OTABSL_ASSERT(b != 0), a / b; +// } +// +// This macro is inspired by +// https://akrzemi1.wordpress.com/2017/05/18/asserts-in-constexpr-functions/ +#if defined(NDEBUG) +#define OTABSL_ASSERT(expr) \ + (false ? static_cast(expr) : static_cast(0)) +#else +#define OTABSL_ASSERT(expr) \ + (OTABSL_PREDICT_TRUE((expr)) ? static_cast(0) \ + : [] { assert(false && #expr); }()) // NOLINT +#endif + +#ifdef OTABSL_HAVE_EXCEPTIONS +#define OTABSL_INTERNAL_TRY try +#define OTABSL_INTERNAL_CATCH_ANY catch (...) +#define OTABSL_INTERNAL_RETHROW do { throw; } while (false) +#else // OTABSL_HAVE_EXCEPTIONS +#define OTABSL_INTERNAL_TRY if (true) +#define OTABSL_INTERNAL_CATCH_ANY else if (false) +#define OTABSL_INTERNAL_RETHROW do {} while (false) +#endif // OTABSL_HAVE_EXCEPTIONS + +#endif // OTABSL_BASE_MACROS_H_ diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/optimization.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/optimization.h new file mode 100644 index 000000000..69713654a --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/optimization.h @@ -0,0 +1,181 @@ +// +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ----------------------------------------------------------------------------- +// File: optimization.h +// ----------------------------------------------------------------------------- +// +// This header file defines portable macros for performance optimization. + +#ifndef OTABSL_BASE_OPTIMIZATION_H_ +#define OTABSL_BASE_OPTIMIZATION_H_ + +#include "config.h" + +// OTABSL_BLOCK_TAIL_CALL_OPTIMIZATION +// +// Instructs the compiler to avoid optimizing tail-call recursion. Use of this +// macro is useful when you wish to preserve the existing function order within +// a stack trace for logging, debugging, or profiling purposes. +// +// Example: +// +// int f() { +// int result = g(); +// OTABSL_BLOCK_TAIL_CALL_OPTIMIZATION(); +// return result; +// } +#if defined(__pnacl__) +#define OTABSL_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; } +#elif defined(__clang__) +// Clang will not tail call given inline volatile assembly. +#define OTABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("") +#elif defined(__GNUC__) +// GCC will not tail call given inline volatile assembly. +#define OTABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("") +#elif defined(_MSC_VER) +#include +// The __nop() intrinsic blocks the optimisation. +#define OTABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __nop() +#else +#define OTABSL_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; } +#endif + +// OTABSL_CACHELINE_SIZE +// +// Explicitly defines the size of the L1 cache for purposes of alignment. +// Setting the cacheline size allows you to specify that certain objects be +// aligned on a cacheline boundary with `OTABSL_CACHELINE_ALIGNED` declarations. +// (See below.) +// +// NOTE: this macro should be replaced with the following C++17 features, when +// those are generally available: +// +// * `std::hardware_constructive_interference_size` +// * `std::hardware_destructive_interference_size` +// +// See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0154r1.html +// for more information. +#if defined(__GNUC__) +// Cache line alignment +#if defined(__i386__) || defined(__x86_64__) +#define OTABSL_CACHELINE_SIZE 64 +#elif defined(__powerpc64__) +#define OTABSL_CACHELINE_SIZE 128 +#elif defined(__aarch64__) +// We would need to read special register ctr_el0 to find out L1 dcache size. +// This value is a good estimate based on a real aarch64 machine. +#define OTABSL_CACHELINE_SIZE 64 +#elif defined(__arm__) +// Cache line sizes for ARM: These values are not strictly correct since +// cache line sizes depend on implementations, not architectures. There +// are even implementations with cache line sizes configurable at boot +// time. +#if defined(__ARM_ARCH_5T__) +#define OTABSL_CACHELINE_SIZE 32 +#elif defined(__ARM_ARCH_7A__) +#define OTABSL_CACHELINE_SIZE 64 +#endif +#endif + +#ifndef OTABSL_CACHELINE_SIZE +// A reasonable default guess. Note that overestimates tend to waste more +// space, while underestimates tend to waste more time. +#define OTABSL_CACHELINE_SIZE 64 +#endif + +// OTABSL_CACHELINE_ALIGNED +// +// Indicates that the declared object be cache aligned using +// `OTABSL_CACHELINE_SIZE` (see above). Cacheline aligning objects allows you to +// load a set of related objects in the L1 cache for performance improvements. +// Cacheline aligning objects properly allows constructive memory sharing and +// prevents destructive (or "false") memory sharing. +// +// NOTE: this macro should be replaced with usage of `alignas()` using +// `std::hardware_constructive_interference_size` and/or +// `std::hardware_destructive_interference_size` when available within C++17. +// +// See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0154r1.html +// for more information. +// +// On some compilers, `OTABSL_CACHELINE_ALIGNED` expands to an `__attribute__` +// or `__declspec` attribute. For compilers where this is not known to work, +// the macro expands to nothing. +// +// No further guarantees are made here. The result of applying the macro +// to variables and types is always implementation-defined. +// +// WARNING: It is easy to use this attribute incorrectly, even to the point +// of causing bugs that are difficult to diagnose, crash, etc. It does not +// of itself guarantee that objects are aligned to a cache line. +// +// NOTE: Some compilers are picky about the locations of annotations such as +// this attribute, so prefer to put it at the beginning of your declaration. +// For example, +// +// OTABSL_CACHELINE_ALIGNED static Foo* foo = ... +// +// class OTABSL_CACHELINE_ALIGNED Bar { ... +// +// Recommendations: +// +// 1) Consult compiler documentation; this comment is not kept in sync as +// toolchains evolve. +// 2) Verify your use has the intended effect. This often requires inspecting +// the generated machine code. +// 3) Prefer applying this attribute to individual variables. Avoid +// applying it to types. This tends to localize the effect. +#define OTABSL_CACHELINE_ALIGNED __attribute__((aligned(OTABSL_CACHELINE_SIZE))) +#elif defined(_MSC_VER) +#define OTABSL_CACHELINE_SIZE 64 +#define OTABSL_CACHELINE_ALIGNED __declspec(align(OTABSL_CACHELINE_SIZE)) +#else +#define OTABSL_CACHELINE_SIZE 64 +#define OTABSL_CACHELINE_ALIGNED +#endif + +// OTABSL_PREDICT_TRUE, OTABSL_PREDICT_FALSE +// +// Enables the compiler to prioritize compilation using static analysis for +// likely paths within a boolean branch. +// +// Example: +// +// if (OTABSL_PREDICT_TRUE(expression)) { +// return result; // Faster if more likely +// } else { +// return 0; +// } +// +// Compilers can use the information that a certain branch is not likely to be +// taken (for instance, a CHECK failure) to optimize for the common case in +// the absence of better information (ie. compiling gcc with `-fprofile-arcs`). +// +// Recommendation: Modern CPUs dynamically predict branch execution paths, +// typically with accuracy greater than 97%. As a result, annotating every +// branch in a codebase is likely counterproductive; however, annotating +// specific branches that are both hot and consistently mispredicted is likely +// to yield performance improvements. +#if OTABSL_HAVE_BUILTIN(__builtin_expect) || \ + (defined(__GNUC__) && !defined(__clang__)) +#define OTABSL_PREDICT_FALSE(x) (__builtin_expect(x, 0)) +#define OTABSL_PREDICT_TRUE(x) (__builtin_expect(false || (x), true)) +#else +#define OTABSL_PREDICT_FALSE(x) (x) +#define OTABSL_PREDICT_TRUE(x) (x) +#endif + +#endif // OTABSL_BASE_OPTIMIZATION_H_ diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/options.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/options.h new file mode 100644 index 000000000..c4b00a3d3 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/options.h @@ -0,0 +1,216 @@ +#ifndef OTABSL_BASE_OPTIONS_H_ +#define OTABSL_BASE_OPTIONS_H_ + +// Copyright 2019 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ----------------------------------------------------------------------------- +// File: options.h +// ----------------------------------------------------------------------------- +// +// This file contains Abseil configuration options for setting specific +// implementations instead of letting Abseil determine which implementation to +// use at compile-time. Setting these options may be useful for package or build +// managers who wish to guarantee ABI stability within binary builds (which are +// otherwise difficult to enforce). +// +// *** IMPORTANT NOTICE FOR PACKAGE MANAGERS: It is important that +// maintainers of package managers who wish to package Abseil read and +// understand this file! *** +// +// Abseil contains a number of possible configuration endpoints, based on +// parameters such as the detected platform, language version, or command-line +// flags used to invoke the underlying binary. As is the case with all +// libraries, binaries which contain Abseil code must ensure that separate +// packages use the same compiled copy of Abseil to avoid a diamond dependency +// problem, which can occur if two packages built with different Abseil +// configuration settings are linked together. Diamond dependency problems in +// C++ may manifest as violations to the One Definition Rule (ODR) (resulting in +// linker errors), or undefined behavior (resulting in crashes). +// +// Diamond dependency problems can be avoided if all packages utilize the same +// exact version of Abseil. Building from source code with the same compilation +// parameters is the easiest way to avoid such dependency problems. However, for +// package managers who cannot control such compilation parameters, we are +// providing the file to allow you to inject ABI (Application Binary Interface) +// stability across builds. Settings options in this file will neither change +// API nor ABI, providing a stable copy of Abseil between packages. +// +// Care must be taken to keep options within these configurations isolated +// from any other dynamic settings, such as command-line flags which could alter +// these options. This file is provided specifically to help build and package +// managers provide a stable copy of Abseil within their libraries and binaries; +// other developers should not have need to alter the contents of this file. +// +// ----------------------------------------------------------------------------- +// Usage +// ----------------------------------------------------------------------------- +// +// For any particular package release, set the appropriate definitions within +// this file to whatever value makes the most sense for your package(s). Note +// that, by default, most of these options, at the moment, affect the +// implementation of types; future options may affect other implementation +// details. +// +// NOTE: the defaults within this file all assume that Abseil can select the +// proper Abseil implementation at compile-time, which will not be sufficient +// to guarantee ABI stability to package managers. + +// Include a standard library header to allow configuration based on the +// standard library in use. +// Using C++20 feature-test macros when possible, otherwise fall back to +// ciso646/iso646.h.There are warnings when including ciso646 in C++17 mode +#ifdef __has_include +# if __has_include() +# include +# endif +#elif defined(_MSC_VER) && \ + ((defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L)) +# if _MSC_VER >= 1922 +# include +# endif +#else +# if defined(__GNUC__) && !defined(__clang__) && !defined(__apple_build_version__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wcpp" +# elif defined(__clang__) || defined(__apple_build_version__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wcpp" +# endif +# include +# if defined(__GNUC__) && !defined(__clang__) && !defined(__apple_build_version__) +# pragma GCC diagnostic pop +# elif defined(__clang__) || defined(__apple_build_version__) +# pragma clang diagnostic pop +# endif +#endif + +// ----------------------------------------------------------------------------- +// Type Compatibility Options +// ----------------------------------------------------------------------------- +// +// OTABSL_OPTION_USE_STD_ANY +// +// This option controls whether absl::OTABSL_OPTION_NAMESPACE_NAME::any is implemented as an alias to +// std::any, or as an independent implementation. +// +// A value of 0 means to use Abseil's implementation. This requires only C++11 +// support, and is expected to work on every toolchain we support. +// +// A value of 1 means to use an alias to std::any. This requires that all code +// using Abseil is built in C++17 mode or later. +// +// A value of 2 means to detect the C++ version being used to compile Abseil, +// and use an alias only if a working std::any is available. This option is +// useful when you are building your entire program, including all of its +// dependencies, from source. It should not be used otherwise -- for example, +// if you are distributing Abseil in a binary package manager -- since in +// mode 2, absl::OTABSL_OPTION_NAMESPACE_NAME::any will name a different type, with a different mangled name +// and binary layout, depending on the compiler flags passed by the end user. +// For more info, see https://abseil.io/about/design/dropin-types. +// +// User code should not inspect this macro. To check in the preprocessor if +// absl::OTABSL_OPTION_NAMESPACE_NAME::any is a typedef of std::any, use the feature macro OTABSL_USES_STD_ANY. + +#define OTABSL_OPTION_USE_STD_ANY 0 + + +// OTABSL_OPTION_USE_STD_OPTIONAL +// +// This option controls whether absl::OTABSL_OPTION_NAMESPACE_NAME::optional is implemented as an alias to +// std::optional, or as an independent implementation. +// +// A value of 0 means to use Abseil's implementation. This requires only C++11 +// support, and is expected to work on every toolchain we support. +// +// A value of 1 means to use an alias to std::optional. This requires that all +// code using Abseil is built in C++17 mode or later. +// +// A value of 2 means to detect the C++ version being used to compile Abseil, +// and use an alias only if a working std::optional is available. This option +// is useful when you are building your program from source. It should not be +// used otherwise -- for example, if you are distributing Abseil in a binary +// package manager -- since in mode 2, absl::OTABSL_OPTION_NAMESPACE_NAME::optional will name a different +// type, with a different mangled name and binary layout, depending on the +// compiler flags passed by the end user. For more info, see +// https://abseil.io/about/design/dropin-types. + +// User code should not inspect this macro. To check in the preprocessor if +// absl::OTABSL_OPTION_NAMESPACE_NAME::optional is a typedef of std::optional, use the feature macro +// OTABSL_USES_STD_OPTIONAL. + +#define OTABSL_OPTION_USE_STD_OPTIONAL 0 + + +// OTABSL_OPTION_USE_STD_STRING_VIEW +// +// This option controls whether absl::OTABSL_OPTION_NAMESPACE_NAME::string_view is implemented as an alias to +// std::string_view, or as an independent implementation. +// +// A value of 0 means to use Abseil's implementation. This requires only C++11 +// support, and is expected to work on every toolchain we support. +// +// A value of 1 means to use an alias to std::string_view. This requires that +// all code using Abseil is built in C++17 mode or later. +// +// A value of 2 means to detect the C++ version being used to compile Abseil, +// and use an alias only if a working std::string_view is available. This +// option is useful when you are building your program from source. It should +// not be used otherwise -- for example, if you are distributing Abseil in a +// binary package manager -- since in mode 2, absl::OTABSL_OPTION_NAMESPACE_NAME::string_view will name a +// different type, with a different mangled name and binary layout, depending on +// the compiler flags passed by the end user. For more info, see +// https://abseil.io/about/design/dropin-types. +// +// User code should not inspect this macro. To check in the preprocessor if +// absl::OTABSL_OPTION_NAMESPACE_NAME::string_view is a typedef of std::string_view, use the feature macro +// OTABSL_USES_STD_STRING_VIEW. + +#define OTABSL_OPTION_USE_STD_STRING_VIEW 0 + +// OTABSL_OPTION_USE_STD_VARIANT +// +// This option controls whether absl::OTABSL_OPTION_NAMESPACE_NAME::variant is implemented as an alias to +// std::variant, or as an independent implementation. +// +// A value of 0 means to use Abseil's implementation. This requires only C++11 +// support, and is expected to work on every toolchain we support. +// +// A value of 1 means to use an alias to std::variant. This requires that all +// code using Abseil is built in C++17 mode or later. +// +// A value of 2 means to detect the C++ version being used to compile Abseil, +// and use an alias only if a working std::variant is available. This option +// is useful when you are building your program from source. It should not be +// used otherwise -- for example, if you are distributing Abseil in a binary +// package manager -- since in mode 2, absl::OTABSL_OPTION_NAMESPACE_NAME::variant will name a different +// type, with a different mangled name and binary layout, depending on the +// compiler flags passed by the end user. For more info, see +// https://abseil.io/about/design/dropin-types. +// +// User code should not inspect this macro. To check in the preprocessor if +// absl::OTABSL_OPTION_NAMESPACE_NAME::variant is a typedef of std::variant, use the feature macro +// OTABSL_USES_STD_VARIANT. + +#define OTABSL_OPTION_USE_STD_VARIANT 0 + + +// OTABSL_OPTION_NAMESPACE_NAME +// +// All codes in otabsl are under OTABSL_OPTION_NAMESPACE_NAME, we do not use inline namespace to avoid +// conlict with external Abseil. + +#define OTABSL_OPTION_NAMESPACE_NAME otel_v1 + +#endif // OTABSL_BASE_OPTIONS_H_ diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/policy_checks.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/policy_checks.h new file mode 100644 index 000000000..f86c264fc --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/policy_checks.h @@ -0,0 +1,115 @@ +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ----------------------------------------------------------------------------- +// File: policy_checks.h +// ----------------------------------------------------------------------------- +// +// This header enforces a minimum set of policies at build time, such as the +// supported compiler and library versions. Unsupported configurations are +// reported with `#error`. This enforcement is best effort, so successfully +// compiling this header does not guarantee a supported configuration. + +#ifndef OTABSL_BASE_POLICY_CHECKS_H_ +#define OTABSL_BASE_POLICY_CHECKS_H_ + +// Included for the __GLIBC_PREREQ macro used below. +#include + +// Included for the _STLPORT_VERSION macro used below. +#if defined(__cplusplus) +#include +#endif + +// ----------------------------------------------------------------------------- +// Operating System Check +// ----------------------------------------------------------------------------- + +#if defined(__CYGWIN__) +#error "Cygwin is not supported." +#endif + +// ----------------------------------------------------------------------------- +// Compiler Check +// ----------------------------------------------------------------------------- + +#if 0 /* FIXME: MG */ +// We support MSVC++ 14.0 update 2 and later. +// This minimum will go up. +#if defined(_MSC_FULL_VER) && _MSC_FULL_VER < 190023918 && !defined(__clang__) +#error "This package requires Visual Studio 2015 Update 2 or higher." +#endif +#endif + +// We support gcc 4.7 and later. +// This minimum will go up. +#if defined(__GNUC__) && !defined(__clang__) +#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) +#error "This package requires gcc 4.7 or higher." +#endif +#endif + +// We support Apple Xcode clang 4.2.1 (version 421.11.65) and later. +// This corresponds to Apple Xcode version 4.5. +// This minimum will go up. +#if defined(__apple_build_version__) && __apple_build_version__ < 4211165 +#error "This package requires __apple_build_version__ of 4211165 or higher." +#endif + +// ----------------------------------------------------------------------------- +// C++ Version Check +// ----------------------------------------------------------------------------- + +// Enforce C++11 as the minimum. +#if defined(_MSVC_LANG) +#if _MSVC_LANG < 201103L +#error "C++ versions less than C++11 are not supported." +#endif // _MSVC_LANG < 201103L +#elif defined(__cplusplus) +#if __cplusplus < 201103L +#error "C++ versions less than C++11 are not supported." +#endif // __cplusplus < 201103L +#endif + +// ----------------------------------------------------------------------------- +// Standard Library Check +// ----------------------------------------------------------------------------- + +#if defined(_STLPORT_VERSION) +#error "STLPort is not supported." +#endif + +// ----------------------------------------------------------------------------- +// `char` Size Check +// ----------------------------------------------------------------------------- + +// Abseil currently assumes CHAR_BIT == 8. If you would like to use Abseil on a +// platform where this is not the case, please provide us with the details about +// your platform so we can consider relaxing this requirement. +#if CHAR_BIT != 8 +#error "Abseil assumes CHAR_BIT == 8." +#endif + +// ----------------------------------------------------------------------------- +// `int` Size Check +// ----------------------------------------------------------------------------- + +// Abseil currently assumes that an int is 4 bytes. If you would like to use +// Abseil on a platform where this is not the case, please provide us with the +// details about your platform so we can consider relaxing this requirement. +#if INT_MAX < 2147483647 +#error "Abseil assumes that int is at least 4 bytes. " +#endif + +#endif // OTABSL_BASE_POLICY_CHECKS_H_ diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/port.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/port.h new file mode 100644 index 000000000..aaba551b5 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/base/port.h @@ -0,0 +1,26 @@ +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// This files is a forwarding header for other headers containing various +// portability macros and functions. +// This file is used for both C and C++! + +#ifndef OTABSL_BASE_PORT_H_ +#define OTABSL_BASE_PORT_H_ + +#include "attributes.h" +#include "config.h" +#include "optimization.h" + +#endif // OTABSL_BASE_PORT_H_ diff --git a/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/meta/type_traits.h b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/meta/type_traits.h new file mode 100644 index 000000000..dbd034887 --- /dev/null +++ b/ext/opentelemetry-cpp-api-only/include/opentelemetry/nostd/internal/absl/meta/type_traits.h @@ -0,0 +1,779 @@ +// +// Copyright 2017 The Abseil Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ----------------------------------------------------------------------------- +// type_traits.h +// ----------------------------------------------------------------------------- +// +// This file contains C++11-compatible versions of standard API +// functions for determining the characteristics of types. Such traits can +// support type inference, classification, and transformation, as well as +// make it easier to write templates based on generic type behavior. +// +// See https://en.cppreference.com/w/cpp/header/type_traits +// +// WARNING: use of many of the constructs in this header will count as "complex +// template metaprogramming", so before proceeding, please carefully consider +// https://google.github.io/styleguide/cppguide.html#Template_metaprogramming +// +// WARNING: using template metaprogramming to detect or depend on API +// features is brittle and not guaranteed. Neither the standard library nor +// Abseil provides any guarantee that APIs are stable in the face of template +// metaprogramming. Use with caution. +#ifndef OTABSL_META_TYPE_TRAITS_H_ +#define OTABSL_META_TYPE_TRAITS_H_ + +#include +#include +#include + +#include "../base/config.h" + +// MSVC constructibility traits do not detect destructor properties and so our +// implementations should not use them as a source-of-truth. +#if defined(_MSC_VER) && !defined(__clang__) && !defined(__GNUC__) +#define OTABSL_META_INTERNAL_STD_CONSTRUCTION_TRAITS_DONT_CHECK_DESTRUCTION 1 +#endif + +namespace absl { +OTABSL_NAMESPACE_BEGIN + +// Defined and documented later on in this file. +template +struct is_trivially_destructible; + +// Defined and documented later on in this file. +template +struct is_trivially_move_assignable; + +namespace type_traits_internal { + +// Silence MSVC warnings about the destructor being defined as deleted. +#if defined(_MSC_VER) && !defined(__GNUC__) +#pragma warning(push) +#pragma warning(disable : 4624) +#endif // defined(_MSC_VER) && !defined(__GNUC__) + +template +union SingleMemberUnion { + T t; +}; + +// Restore the state of the destructor warning that was silenced above. +#if defined(_MSC_VER) && !defined(__GNUC__) +#pragma warning(pop) +#endif // defined(_MSC_VER) && !defined(__GNUC__) + +template +struct IsTriviallyMoveConstructibleObject + : std::integral_constant< + bool, std::is_move_constructible< + type_traits_internal::SingleMemberUnion>::value && + absl::OTABSL_OPTION_NAMESPACE_NAME::is_trivially_destructible::value> {}; + +template +struct IsTriviallyCopyConstructibleObject + : std::integral_constant< + bool, std::is_copy_constructible< + type_traits_internal::SingleMemberUnion>::value && + absl::OTABSL_OPTION_NAMESPACE_NAME::is_trivially_destructible::value> {}; + +template +struct IsTriviallyMoveAssignableReference : std::false_type {}; + +template +struct IsTriviallyMoveAssignableReference + : absl::OTABSL_OPTION_NAMESPACE_NAME::is_trivially_move_assignable::type {}; + +template +struct IsTriviallyMoveAssignableReference + : absl::OTABSL_OPTION_NAMESPACE_NAME::is_trivially_move_assignable::type {}; + +template +struct VoidTImpl { + using type = void; +}; + +//////////////////////////////// +// Library Fundamentals V2 TS // +//////////////////////////////// + +// NOTE: The `is_detected` family of templates here differ from the library +// fundamentals specification in that for library fundamentals, `Op` is +// evaluated as soon as the type `is_detected` undergoes +// substitution, regardless of whether or not the `::value` is accessed. That +// is inconsistent with all other standard traits and prevents lazy evaluation +// in larger contexts (such as if the `is_detected` check is a trailing argument +// of a `conjunction`. This implementation opts to instead be lazy in the same +// way that the standard traits are (this "defect" of the detection idiom +// specifications has been reported). + +template class Op, class... Args> +struct is_detected_impl { + using type = std::false_type; +}; + +template