couchbase 3.5.4 → 3.5.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (441) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/ext/CMakeLists.txt +8 -6
  4. data/ext/cache/cpm/{CPM_0.38.6.cmake → CPM_0.40.5.cmake} +152 -22
  5. data/ext/cache/extconf_include.rb +3 -3
  6. data/ext/cache/mozilla-ca-bundle.crt +32 -87
  7. data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
  8. data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/CMakeLists.txt +30 -6
  9. data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/cmake/utils.cmake +13 -2
  10. data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/async_logger-inl.h +5 -7
  11. data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/mpmc_blocking_q.h +3 -3
  12. data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/os-inl.h +3 -3
  13. data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/thread_pool-inl.h +3 -8
  14. data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/thread_pool.h +3 -14
  15. data/ext/cache/{fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/include/fmt → spdlog/7251ead404dccd824789f8f3a13df2a6fb56440c/spdlog/include/spdlog/fmt/bundled}/base.h +47 -31
  16. data/ext/cache/{fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/include/fmt → spdlog/7251ead404dccd824789f8f3a13df2a6fb56440c/spdlog/include/spdlog/fmt/bundled}/format-inl.h +32 -8
  17. data/ext/cache/{fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/include/fmt → spdlog/7251ead404dccd824789f8f3a13df2a6fb56440c/spdlog/include/spdlog/fmt/bundled}/format.h +22 -14
  18. data/ext/cache/{fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/include/fmt → spdlog/7251ead404dccd824789f8f3a13df2a6fb56440c/spdlog/include/spdlog/fmt/bundled}/ranges.h +1 -1
  19. data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/mdc.h +4 -0
  20. data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/pattern_formatter-inl.h +16 -2
  21. data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/ansicolor_sink.h +1 -1
  22. data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/base_sink.h +4 -4
  23. data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/callback_sink.h +1 -1
  24. data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/daily_file_sink.h +3 -0
  25. data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/hourly_file_sink.h +2 -0
  26. data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/msvc_sink.h +1 -1
  27. data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/rotating_file_sink-inl.h +1 -1
  28. data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/syslog_sink.h +3 -2
  29. data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/wincolor_sink-inl.h +9 -0
  30. data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/version.h +2 -2
  31. data/ext/cache/{fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/src/format.cc → spdlog/7251ead404dccd824789f8f3a13df2a6fb56440c/spdlog/src/bundled_fmtlib_format.cpp} +10 -5
  32. data/ext/couchbase/CMakeLists.txt +3 -2
  33. data/ext/couchbase/cmake/APKBUILD.in +54 -0
  34. data/ext/couchbase/cmake/Backtrace.cmake +3 -1
  35. data/ext/couchbase/cmake/CPM.cmake +1 -1
  36. data/ext/couchbase/cmake/CompilerWarnings.cmake +0 -5
  37. data/ext/couchbase/cmake/Packaging.cmake +174 -11
  38. data/ext/couchbase/cmake/RPath.cmake +10 -0
  39. data/ext/couchbase/cmake/Testing.cmake +0 -4
  40. data/ext/couchbase/cmake/ThirdPartyDependencies.cmake +7 -26
  41. data/ext/couchbase/cmake/VersionInfo.cmake +4 -0
  42. data/ext/couchbase/cmake/build_version.hxx.in +1 -0
  43. data/ext/couchbase/cmake/couchbase-cxx-client.spec.in +2 -2
  44. data/ext/couchbase/cmake/couchbase_cxx_client.pc.in +2 -2
  45. data/ext/couchbase/core/agent_config.cxx +1 -1
  46. data/ext/couchbase/core/agent_group_config.cxx +1 -1
  47. data/ext/couchbase/core/bucket.cxx +9 -9
  48. data/ext/couchbase/core/cluster.cxx +0 -2
  49. data/ext/couchbase/core/cluster_agent_config.cxx +1 -1
  50. data/ext/couchbase/core/collections_component.cxx +1 -1
  51. data/ext/couchbase/core/columnar/agent_config.cxx +2 -2
  52. data/ext/couchbase/core/columnar/error.hxx +0 -1
  53. data/ext/couchbase/core/columnar/query_component.cxx +2 -2
  54. data/ext/couchbase/core/config_profiles.cxx +1 -1
  55. data/ext/couchbase/core/core_sdk_shim.cxx +1 -1
  56. data/ext/couchbase/core/crud_component.cxx +1 -1
  57. data/ext/couchbase/core/design_document_namespace_fmt.hxx +1 -1
  58. data/ext/couchbase/core/diagnostics_fmt.hxx +1 -1
  59. data/ext/couchbase/core/document_id.cxx +1 -1
  60. data/ext/couchbase/core/document_id_fmt.hxx +1 -1
  61. data/ext/couchbase/core/error_context/analytics_json.hxx +3 -1
  62. data/ext/couchbase/core/error_context/key_value_json.hxx +1 -1
  63. data/ext/couchbase/core/error_context/query_public_json.hxx +1 -1
  64. data/ext/couchbase/core/error_context/subdocument_json.hxx +1 -1
  65. data/ext/couchbase/core/fmt/key_value_error_map_attribute.hxx +1 -1
  66. data/ext/couchbase/core/fmt/key_value_extended_error_info.hxx +1 -1
  67. data/ext/couchbase/core/fmt/key_value_status_code.hxx +1 -1
  68. data/ext/couchbase/core/http_component.cxx +3 -3
  69. data/ext/couchbase/core/impl/analytics.cxx +1 -0
  70. data/ext/couchbase/core/impl/best_effort_retry_strategy.cxx +1 -1
  71. data/ext/couchbase/core/impl/collection.cxx +28 -4
  72. data/ext/couchbase/core/impl/date_range.cxx +2 -2
  73. data/ext/couchbase/core/impl/date_range_query.cxx +2 -2
  74. data/ext/couchbase/core/impl/dns_srv_tracker.cxx +1 -1
  75. data/ext/couchbase/core/impl/error.cxx +27 -4
  76. data/ext/couchbase/core/impl/expiry.cxx +2 -2
  77. data/ext/couchbase/core/impl/fail_fast_retry_strategy.cxx +1 -2
  78. data/ext/couchbase/core/impl/get_replica.hxx +2 -0
  79. data/ext/couchbase/core/impl/key_value_error_context.cxx +6 -4
  80. data/ext/couchbase/core/impl/lookup_in_replica.hxx +2 -0
  81. data/ext/couchbase/core/impl/numeric_range.cxx +1 -1
  82. data/ext/couchbase/core/impl/observe_seqno.hxx +2 -0
  83. data/ext/couchbase/core/impl/query.cxx +1 -0
  84. data/ext/couchbase/core/impl/query_error_context.cxx +3 -2
  85. data/ext/couchbase/core/impl/scope.cxx +5 -6
  86. data/ext/couchbase/core/impl/search.cxx +3 -1
  87. data/ext/couchbase/core/io/config_tracker.cxx +1 -1
  88. data/ext/couchbase/core/io/dns_client.cxx +23 -8
  89. data/ext/couchbase/core/io/http_command.hxx +2 -2
  90. data/ext/couchbase/core/io/http_parser.cxx +1 -1
  91. data/ext/couchbase/core/io/http_session.cxx +4 -0
  92. data/ext/couchbase/core/io/http_session.hxx +4 -2
  93. data/ext/couchbase/core/io/mcbp_command.hxx +2 -2
  94. data/ext/couchbase/core/key_value_config.cxx +2 -2
  95. data/ext/couchbase/core/logger/logger.hxx +1 -1
  96. data/ext/couchbase/core/management/rbac_fmt.hxx +1 -1
  97. data/ext/couchbase/core/mcbp/operation_queue.cxx +1 -1
  98. data/ext/couchbase/core/mcbp/packet.cxx +1 -1
  99. data/ext/couchbase/core/meta/features.hxx +11 -0
  100. data/ext/couchbase/core/meta/version.cxx +48 -7
  101. data/ext/couchbase/core/operations/document_analytics.cxx +23 -17
  102. data/ext/couchbase/core/operations/document_analytics.hxx +1 -0
  103. data/ext/couchbase/core/operations/document_append.hxx +2 -0
  104. data/ext/couchbase/core/operations/document_decrement.hxx +2 -0
  105. data/ext/couchbase/core/operations/document_exists.hxx +2 -0
  106. data/ext/couchbase/core/operations/document_get.hxx +2 -0
  107. data/ext/couchbase/core/operations/document_get_all_replicas.hxx +2 -0
  108. data/ext/couchbase/core/operations/document_get_and_lock.hxx +2 -0
  109. data/ext/couchbase/core/operations/document_get_and_touch.hxx +2 -0
  110. data/ext/couchbase/core/operations/document_get_any_replica.hxx +2 -0
  111. data/ext/couchbase/core/operations/document_get_projected.hxx +2 -0
  112. data/ext/couchbase/core/operations/document_increment.hxx +2 -0
  113. data/ext/couchbase/core/operations/document_insert.hxx +2 -0
  114. data/ext/couchbase/core/operations/document_lookup_in.hxx +2 -0
  115. data/ext/couchbase/core/operations/document_lookup_in_all_replicas.hxx +2 -0
  116. data/ext/couchbase/core/operations/document_lookup_in_any_replica.hxx +2 -0
  117. data/ext/couchbase/core/operations/document_mutate_in.hxx +2 -0
  118. data/ext/couchbase/core/operations/document_prepend.hxx +2 -0
  119. data/ext/couchbase/core/operations/document_query.hxx +1 -0
  120. data/ext/couchbase/core/operations/document_remove.hxx +2 -0
  121. data/ext/couchbase/core/operations/document_replace.hxx +2 -0
  122. data/ext/couchbase/core/operations/document_search.hxx +1 -0
  123. data/ext/couchbase/core/operations/document_touch.hxx +2 -0
  124. data/ext/couchbase/core/operations/document_unlock.hxx +2 -0
  125. data/ext/couchbase/core/operations/document_upsert.hxx +2 -0
  126. data/ext/couchbase/core/operations/document_view.hxx +1 -0
  127. data/ext/couchbase/core/operations/http_noop.hxx +2 -0
  128. data/ext/couchbase/core/operations/management/CMakeLists.txt +0 -1
  129. data/ext/couchbase/core/operations/management/analytics_dataset_create.cxx +1 -1
  130. data/ext/couchbase/core/operations/management/analytics_dataset_create.hxx +1 -0
  131. data/ext/couchbase/core/operations/management/analytics_dataset_drop.cxx +1 -1
  132. data/ext/couchbase/core/operations/management/analytics_dataset_drop.hxx +1 -0
  133. data/ext/couchbase/core/operations/management/analytics_dataset_get_all.hxx +1 -0
  134. data/ext/couchbase/core/operations/management/analytics_dataverse_create.cxx +1 -1
  135. data/ext/couchbase/core/operations/management/analytics_dataverse_create.hxx +1 -0
  136. data/ext/couchbase/core/operations/management/analytics_dataverse_drop.cxx +1 -1
  137. data/ext/couchbase/core/operations/management/analytics_dataverse_drop.hxx +1 -0
  138. data/ext/couchbase/core/operations/management/analytics_get_pending_mutations.cxx +1 -1
  139. data/ext/couchbase/core/operations/management/analytics_get_pending_mutations.hxx +2 -0
  140. data/ext/couchbase/core/operations/management/analytics_index_create.hxx +1 -0
  141. data/ext/couchbase/core/operations/management/analytics_index_drop.cxx +1 -1
  142. data/ext/couchbase/core/operations/management/analytics_index_drop.hxx +1 -0
  143. data/ext/couchbase/core/operations/management/analytics_index_get_all.hxx +1 -0
  144. data/ext/couchbase/core/operations/management/analytics_link_connect.cxx +1 -1
  145. data/ext/couchbase/core/operations/management/analytics_link_connect.hxx +1 -0
  146. data/ext/couchbase/core/operations/management/analytics_link_create.hxx +1 -0
  147. data/ext/couchbase/core/operations/management/analytics_link_disconnect.cxx +1 -1
  148. data/ext/couchbase/core/operations/management/analytics_link_disconnect.hxx +1 -0
  149. data/ext/couchbase/core/operations/management/analytics_link_drop.cxx +1 -1
  150. data/ext/couchbase/core/operations/management/analytics_link_drop.hxx +1 -0
  151. data/ext/couchbase/core/operations/management/analytics_link_get_all.cxx +24 -16
  152. data/ext/couchbase/core/operations/management/analytics_link_get_all.hxx +4 -3
  153. data/ext/couchbase/core/operations/management/analytics_link_replace.hxx +1 -0
  154. data/ext/couchbase/core/operations/management/analytics_link_utils.hxx +4 -3
  155. data/ext/couchbase/core/operations/management/bucket_create.hxx +1 -0
  156. data/ext/couchbase/core/operations/management/bucket_describe.cxx +1 -1
  157. data/ext/couchbase/core/operations/management/bucket_describe.hxx +1 -0
  158. data/ext/couchbase/core/operations/management/bucket_drop.cxx +1 -1
  159. data/ext/couchbase/core/operations/management/bucket_drop.hxx +1 -0
  160. data/ext/couchbase/core/operations/management/bucket_flush.cxx +1 -1
  161. data/ext/couchbase/core/operations/management/bucket_flush.hxx +1 -0
  162. data/ext/couchbase/core/operations/management/bucket_get.cxx +1 -1
  163. data/ext/couchbase/core/operations/management/bucket_get.hxx +1 -0
  164. data/ext/couchbase/core/operations/management/bucket_get_all.hxx +1 -0
  165. data/ext/couchbase/core/operations/management/bucket_update.hxx +1 -0
  166. data/ext/couchbase/core/operations/management/change_password.cxx +1 -1
  167. data/ext/couchbase/core/operations/management/change_password.hxx +1 -0
  168. data/ext/couchbase/core/operations/management/cluster_describe.hxx +1 -0
  169. data/ext/couchbase/core/operations/management/cluster_developer_preview_enable.hxx +1 -0
  170. data/ext/couchbase/core/operations/management/collection_create.cxx +1 -1
  171. data/ext/couchbase/core/operations/management/collection_create.hxx +2 -0
  172. data/ext/couchbase/core/operations/management/collection_drop.cxx +1 -1
  173. data/ext/couchbase/core/operations/management/collection_drop.hxx +1 -0
  174. data/ext/couchbase/core/operations/management/collection_update.cxx +1 -1
  175. data/ext/couchbase/core/operations/management/collection_update.hxx +2 -0
  176. data/ext/couchbase/core/operations/management/collections_manifest_get.hxx +2 -0
  177. data/ext/couchbase/core/operations/management/eventing_deploy_function.cxx +1 -1
  178. data/ext/couchbase/core/operations/management/eventing_deploy_function.hxx +3 -2
  179. data/ext/couchbase/core/operations/management/eventing_drop_function.cxx +1 -1
  180. data/ext/couchbase/core/operations/management/eventing_drop_function.hxx +3 -2
  181. data/ext/couchbase/core/operations/management/eventing_get_all_functions.hxx +3 -2
  182. data/ext/couchbase/core/operations/management/eventing_get_function.cxx +1 -1
  183. data/ext/couchbase/core/operations/management/eventing_get_function.hxx +3 -2
  184. data/ext/couchbase/core/operations/management/eventing_get_status.hxx +3 -2
  185. data/ext/couchbase/core/operations/management/eventing_pause_function.cxx +1 -1
  186. data/ext/couchbase/core/operations/management/eventing_pause_function.hxx +3 -2
  187. data/ext/couchbase/core/operations/management/eventing_resume_function.cxx +1 -1
  188. data/ext/couchbase/core/operations/management/eventing_resume_function.hxx +3 -2
  189. data/ext/couchbase/core/operations/management/eventing_undeploy_function.cxx +1 -1
  190. data/ext/couchbase/core/operations/management/eventing_undeploy_function.hxx +3 -2
  191. data/ext/couchbase/core/operations/management/eventing_upsert_function.cxx +1 -2
  192. data/ext/couchbase/core/operations/management/eventing_upsert_function.hxx +3 -2
  193. data/ext/couchbase/core/operations/management/freeform.hxx +2 -0
  194. data/ext/couchbase/core/operations/management/group_drop.cxx +1 -1
  195. data/ext/couchbase/core/operations/management/group_drop.hxx +1 -0
  196. data/ext/couchbase/core/operations/management/group_get.cxx +1 -1
  197. data/ext/couchbase/core/operations/management/group_get.hxx +1 -0
  198. data/ext/couchbase/core/operations/management/group_get_all.hxx +1 -0
  199. data/ext/couchbase/core/operations/management/group_upsert.hxx +1 -0
  200. data/ext/couchbase/core/operations/management/query_index_build.hxx +7 -5
  201. data/ext/couchbase/core/operations/management/query_index_build_deferred.hxx +3 -0
  202. data/ext/couchbase/core/operations/management/query_index_create.cxx +1 -1
  203. data/ext/couchbase/core/operations/management/query_index_create.hxx +1 -0
  204. data/ext/couchbase/core/operations/management/query_index_drop.cxx +1 -1
  205. data/ext/couchbase/core/operations/management/query_index_drop.hxx +1 -0
  206. data/ext/couchbase/core/operations/management/query_index_get_all.hxx +2 -0
  207. data/ext/couchbase/core/operations/management/query_index_get_all_deferred.hxx +3 -0
  208. data/ext/couchbase/core/operations/management/role_get_all.hxx +1 -0
  209. data/ext/couchbase/core/operations/management/scope_create.cxx +1 -1
  210. data/ext/couchbase/core/operations/management/scope_create.hxx +1 -0
  211. data/ext/couchbase/core/operations/management/scope_drop.cxx +1 -1
  212. data/ext/couchbase/core/operations/management/scope_drop.hxx +1 -0
  213. data/ext/couchbase/core/operations/management/scope_get_all.cxx +1 -1
  214. data/ext/couchbase/core/operations/management/scope_get_all.hxx +1 -0
  215. data/ext/couchbase/core/operations/management/search_get_stats.hxx +1 -0
  216. data/ext/couchbase/core/operations/management/search_index_analyze_document.cxx +1 -1
  217. data/ext/couchbase/core/operations/management/search_index_analyze_document.hxx +1 -0
  218. data/ext/couchbase/core/operations/management/search_index_control_ingest.cxx +1 -1
  219. data/ext/couchbase/core/operations/management/search_index_control_ingest.hxx +1 -0
  220. data/ext/couchbase/core/operations/management/search_index_control_plan_freeze.cxx +1 -1
  221. data/ext/couchbase/core/operations/management/search_index_control_plan_freeze.hxx +1 -0
  222. data/ext/couchbase/core/operations/management/search_index_control_query.cxx +1 -1
  223. data/ext/couchbase/core/operations/management/search_index_control_query.hxx +1 -0
  224. data/ext/couchbase/core/operations/management/search_index_drop.cxx +1 -1
  225. data/ext/couchbase/core/operations/management/search_index_drop.hxx +1 -0
  226. data/ext/couchbase/core/operations/management/search_index_get.cxx +1 -1
  227. data/ext/couchbase/core/operations/management/search_index_get.hxx +1 -0
  228. data/ext/couchbase/core/operations/management/search_index_get_all.cxx +1 -1
  229. data/ext/couchbase/core/operations/management/search_index_get_all.hxx +1 -0
  230. data/ext/couchbase/core/operations/management/search_index_get_documents_count.cxx +1 -1
  231. data/ext/couchbase/core/operations/management/search_index_get_documents_count.hxx +2 -0
  232. data/ext/couchbase/core/operations/management/search_index_get_stats.cxx +1 -1
  233. data/ext/couchbase/core/operations/management/search_index_get_stats.hxx +1 -0
  234. data/ext/couchbase/core/operations/management/search_index_upsert.cxx +1 -1
  235. data/ext/couchbase/core/operations/management/search_index_upsert.hxx +1 -0
  236. data/ext/couchbase/core/operations/management/user_drop.hxx +1 -0
  237. data/ext/couchbase/core/operations/management/user_get.hxx +1 -0
  238. data/ext/couchbase/core/operations/management/user_get_all.hxx +1 -0
  239. data/ext/couchbase/core/operations/management/user_upsert.cxx +3 -3
  240. data/ext/couchbase/core/operations/management/user_upsert.hxx +1 -0
  241. data/ext/couchbase/core/operations/management/view_index_drop.cxx +1 -1
  242. data/ext/couchbase/core/operations/management/view_index_drop.hxx +1 -0
  243. data/ext/couchbase/core/operations/management/view_index_get.cxx +1 -1
  244. data/ext/couchbase/core/operations/management/view_index_get.hxx +1 -0
  245. data/ext/couchbase/core/operations/management/view_index_get_all.cxx +1 -1
  246. data/ext/couchbase/core/operations/management/view_index_get_all.hxx +2 -0
  247. data/ext/couchbase/core/operations/management/view_index_upsert.cxx +1 -1
  248. data/ext/couchbase/core/operations/management/view_index_upsert.hxx +1 -0
  249. data/ext/couchbase/core/origin.cxx +3 -2
  250. data/ext/couchbase/core/platform/base64.h +8 -8
  251. data/ext/couchbase/core/protocol/client_opcode_fmt.hxx +1 -1
  252. data/ext/couchbase/core/protocol/client_response.hxx +1 -1
  253. data/ext/couchbase/core/protocol/frame_info_id_fmt.hxx +1 -1
  254. data/ext/couchbase/core/protocol/hello_feature_fmt.hxx +1 -1
  255. data/ext/couchbase/core/protocol/magic_fmt.hxx +1 -1
  256. data/ext/couchbase/core/protocol/server_opcode_fmt.hxx +1 -1
  257. data/ext/couchbase/core/query_context.hxx +7 -6
  258. data/ext/couchbase/core/retry_orchestrator.cxx +1 -1
  259. data/ext/couchbase/core/sasl/CMakeLists.txt +0 -1
  260. data/ext/couchbase/core/sasl/error_fmt.h +1 -1
  261. data/ext/couchbase/core/seed_config.cxx +2 -2
  262. data/ext/couchbase/core/service_type_fmt.hxx +1 -1
  263. data/ext/couchbase/core/topology/capabilities_fmt.hxx +1 -1
  264. data/ext/couchbase/core/topology/collections_manifest_fmt.hxx +2 -1
  265. data/ext/couchbase/core/topology/configuration_fmt.hxx +1 -1
  266. data/ext/couchbase/core/transactions/async_attempt_context.cxx +1 -1
  267. data/ext/couchbase/core/transactions/async_attempt_context.hxx +9 -22
  268. data/ext/couchbase/core/transactions/attempt_context.cxx +1 -1
  269. data/ext/couchbase/core/transactions/attempt_context.hxx +6 -33
  270. data/ext/couchbase/core/transactions/attempt_context_impl.cxx +41 -41
  271. data/ext/couchbase/core/transactions/attempt_context_impl.hxx +15 -16
  272. data/ext/couchbase/core/transactions/exceptions_fmt.hxx +1 -1
  273. data/ext/couchbase/core/transactions/internal/atr_cleanup_entry.hxx +1 -1
  274. data/ext/couchbase/core/transactions/internal/client_record.hxx +4 -3
  275. data/ext/couchbase/core/transactions/internal/doc_record_fmt.hxx +1 -1
  276. data/ext/couchbase/core/transactions/internal/exceptions_internal.hxx +0 -2
  277. data/ext/couchbase/core/transactions/internal/exceptions_internal_fmt.hxx +1 -1
  278. data/ext/couchbase/core/transactions/internal/logging.hxx +2 -0
  279. data/ext/couchbase/core/transactions/internal/transaction_context.hxx +3 -0
  280. data/ext/couchbase/core/transactions/result_fmt.hxx +1 -1
  281. data/ext/couchbase/core/transactions/transaction_context.cxx +12 -2
  282. data/ext/couchbase/core/transactions/transaction_get_result.hxx +0 -20
  283. data/ext/couchbase/core/transactions/transaction_links.hxx +1 -1
  284. data/ext/couchbase/core/utils/join_strings.hxx +2 -2
  285. data/ext/couchbase/core/utils/keyspace.hxx +2 -1
  286. data/ext/couchbase/core/utils/url_codec.cxx +1 -1
  287. data/ext/couchbase/couchbase/common_options.hxx +16 -1
  288. data/ext/couchbase/couchbase/fmt/analytics_scan_consistency.hxx +0 -2
  289. data/ext/couchbase/couchbase/fmt/analytics_status.hxx +0 -2
  290. data/ext/couchbase/couchbase/fmt/cas.hxx +0 -2
  291. data/ext/couchbase/couchbase/fmt/durability_level.hxx +0 -2
  292. data/ext/couchbase/couchbase/fmt/error.hxx +0 -2
  293. data/ext/couchbase/couchbase/fmt/error_context.hxx +0 -2
  294. data/ext/couchbase/couchbase/fmt/mutation_token.hxx +0 -2
  295. data/ext/couchbase/couchbase/fmt/query_profile.hxx +0 -2
  296. data/ext/couchbase/couchbase/fmt/query_scan_consistency.hxx +0 -2
  297. data/ext/couchbase/couchbase/fmt/query_status.hxx +0 -2
  298. data/ext/couchbase/couchbase/fmt/retry_reason.hxx +5 -1
  299. data/ext/couchbase/couchbase/fmt/search_scan_consistency.hxx +0 -2
  300. data/ext/couchbase/couchbase/fmt/tls_verify_mode.hxx +0 -2
  301. data/ext/couchbase/couchbase/fmt/transaction_keyspace.hxx +0 -2
  302. data/ext/couchbase/couchbase/metrics/otel_meter.hxx +16 -20
  303. data/ext/extconf.rb +1 -0
  304. data/ext/rcb_analytics.cxx +7 -7
  305. data/ext/rcb_backend.cxx +6 -1
  306. data/ext/rcb_buckets.cxx +1 -1
  307. data/ext/rcb_collections.cxx +1 -1
  308. data/ext/rcb_crud.cxx +51 -30
  309. data/ext/rcb_diagnostics.cxx +1 -1
  310. data/ext/rcb_exceptions.cxx +3 -2
  311. data/ext/rcb_extras.cxx +1 -1
  312. data/ext/rcb_range_scan.cxx +1 -1
  313. data/ext/rcb_search.cxx +1 -1
  314. data/ext/rcb_users.cxx +2 -2
  315. data/ext/rcb_utils.hxx +32 -0
  316. data/lib/couchbase/logger.rb +3 -3
  317. data/lib/couchbase/options.rb +48 -0
  318. data/lib/couchbase/version.rb +1 -1
  319. metadata +131 -153
  320. data/ext/cache/fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/CMakeLists.txt +0 -520
  321. data/ext/cache/fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/ChangeLog.md +0 -2598
  322. data/ext/cache/fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/LICENSE +0 -27
  323. data/ext/cache/fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/README.md +0 -484
  324. data/ext/cache/fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/src/fmt.cc +0 -135
  325. data/ext/cache/fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/src/os.cc +0 -403
  326. data/ext/cache/fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/support/cmake/FindSetEnv.cmake +0 -7
  327. data/ext/cache/fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/support/cmake/JoinPaths.cmake +0 -26
  328. data/ext/cache/fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/support/cmake/fmt-config.cmake.in +0 -7
  329. data/ext/cache/fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/support/cmake/fmt.pc.in +0 -11
  330. data/ext/cache/spdlog/19df5d3d8e5526c255d27414e09568671ef87483/spdlog/include/spdlog/fmt/bundled/args.h +0 -235
  331. data/ext/cache/spdlog/19df5d3d8e5526c255d27414e09568671ef87483/spdlog/include/spdlog/fmt/bundled/chrono.h +0 -2240
  332. data/ext/cache/spdlog/19df5d3d8e5526c255d27414e09568671ef87483/spdlog/include/spdlog/fmt/bundled/color.h +0 -643
  333. data/ext/cache/spdlog/19df5d3d8e5526c255d27414e09568671ef87483/spdlog/include/spdlog/fmt/bundled/compile.h +0 -535
  334. data/ext/cache/spdlog/19df5d3d8e5526c255d27414e09568671ef87483/spdlog/include/spdlog/fmt/bundled/core.h +0 -2969
  335. data/ext/cache/spdlog/19df5d3d8e5526c255d27414e09568671ef87483/spdlog/include/spdlog/fmt/bundled/format-inl.h +0 -1678
  336. data/ext/cache/spdlog/19df5d3d8e5526c255d27414e09568671ef87483/spdlog/include/spdlog/fmt/bundled/format.h +0 -4535
  337. data/ext/cache/spdlog/19df5d3d8e5526c255d27414e09568671ef87483/spdlog/include/spdlog/fmt/bundled/os.h +0 -455
  338. data/ext/cache/spdlog/19df5d3d8e5526c255d27414e09568671ef87483/spdlog/include/spdlog/fmt/bundled/ostream.h +0 -245
  339. data/ext/cache/spdlog/19df5d3d8e5526c255d27414e09568671ef87483/spdlog/include/spdlog/fmt/bundled/printf.h +0 -675
  340. data/ext/cache/spdlog/19df5d3d8e5526c255d27414e09568671ef87483/spdlog/include/spdlog/fmt/bundled/ranges.h +0 -738
  341. data/ext/cache/spdlog/19df5d3d8e5526c255d27414e09568671ef87483/spdlog/include/spdlog/fmt/bundled/std.h +0 -537
  342. data/ext/cache/spdlog/19df5d3d8e5526c255d27414e09568671ef87483/spdlog/include/spdlog/fmt/bundled/xchar.h +0 -259
  343. data/ext/cache/spdlog/19df5d3d8e5526c255d27414e09568671ef87483/spdlog/src/bundled_fmtlib_format.cpp +0 -46
  344. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/LICENSE +0 -0
  345. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/cmake/ide.cmake +0 -0
  346. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/cmake/pch.h.in +0 -0
  347. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/cmake/spdlog.pc.in +0 -0
  348. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/cmake/spdlogCPack.cmake +0 -0
  349. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/cmake/spdlogConfig.cmake.in +0 -0
  350. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/cmake/version.rc.in +0 -0
  351. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/async.h +0 -0
  352. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/async_logger.h +0 -0
  353. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/cfg/argv.h +0 -0
  354. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/cfg/env.h +0 -0
  355. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/cfg/helpers-inl.h +0 -0
  356. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/cfg/helpers.h +0 -0
  357. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/common-inl.h +0 -0
  358. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/common.h +0 -0
  359. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/backtracer-inl.h +0 -0
  360. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/backtracer.h +0 -0
  361. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/circular_q.h +0 -0
  362. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/console_globals.h +0 -0
  363. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/file_helper-inl.h +0 -0
  364. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/file_helper.h +0 -0
  365. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/fmt_helper.h +0 -0
  366. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/log_msg-inl.h +0 -0
  367. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/log_msg.h +0 -0
  368. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/log_msg_buffer-inl.h +0 -0
  369. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/log_msg_buffer.h +0 -0
  370. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/null_mutex.h +0 -0
  371. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/os.h +0 -0
  372. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/periodic_worker-inl.h +0 -0
  373. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/periodic_worker.h +0 -0
  374. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/registry-inl.h +0 -0
  375. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/registry.h +0 -0
  376. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/synchronous_factory.h +0 -0
  377. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/tcp_client-windows.h +0 -0
  378. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/tcp_client.h +0 -0
  379. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/udp_client-windows.h +0 -0
  380. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/udp_client.h +0 -0
  381. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/details/windows_include.h +0 -0
  382. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/fmt/bin_to_hex.h +0 -0
  383. /data/ext/cache/{fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/include/fmt → spdlog/7251ead404dccd824789f8f3a13df2a6fb56440c/spdlog/include/spdlog/fmt/bundled}/args.h +0 -0
  384. /data/ext/cache/{fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/include/fmt → spdlog/7251ead404dccd824789f8f3a13df2a6fb56440c/spdlog/include/spdlog/fmt/bundled}/chrono.h +0 -0
  385. /data/ext/cache/{fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/include/fmt → spdlog/7251ead404dccd824789f8f3a13df2a6fb56440c/spdlog/include/spdlog/fmt/bundled}/color.h +0 -0
  386. /data/ext/cache/{fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/include/fmt → spdlog/7251ead404dccd824789f8f3a13df2a6fb56440c/spdlog/include/spdlog/fmt/bundled}/compile.h +0 -0
  387. /data/ext/cache/{fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/include/fmt → spdlog/7251ead404dccd824789f8f3a13df2a6fb56440c/spdlog/include/spdlog/fmt/bundled}/core.h +0 -0
  388. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/fmt/bundled/fmt.license.rst +0 -0
  389. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/fmt/bundled/locale.h +0 -0
  390. /data/ext/cache/{fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/include/fmt → spdlog/7251ead404dccd824789f8f3a13df2a6fb56440c/spdlog/include/spdlog/fmt/bundled}/os.h +0 -0
  391. /data/ext/cache/{fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/include/fmt → spdlog/7251ead404dccd824789f8f3a13df2a6fb56440c/spdlog/include/spdlog/fmt/bundled}/ostream.h +0 -0
  392. /data/ext/cache/{fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/include/fmt → spdlog/7251ead404dccd824789f8f3a13df2a6fb56440c/spdlog/include/spdlog/fmt/bundled}/printf.h +0 -0
  393. /data/ext/cache/{fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/include/fmt → spdlog/7251ead404dccd824789f8f3a13df2a6fb56440c/spdlog/include/spdlog/fmt/bundled}/std.h +0 -0
  394. /data/ext/cache/{fmt/141a17a028e6c29914e109691389f6cf87f9cfe3/fmt/include/fmt → spdlog/7251ead404dccd824789f8f3a13df2a6fb56440c/spdlog/include/spdlog/fmt/bundled}/xchar.h +0 -0
  395. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/fmt/chrono.h +0 -0
  396. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/fmt/compile.h +0 -0
  397. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/fmt/fmt.h +0 -0
  398. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/fmt/ostr.h +0 -0
  399. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/fmt/ranges.h +0 -0
  400. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/fmt/std.h +0 -0
  401. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/fmt/xchar.h +0 -0
  402. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/formatter.h +0 -0
  403. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/fwd.h +0 -0
  404. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/logger-inl.h +0 -0
  405. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/logger.h +0 -0
  406. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/pattern_formatter.h +0 -0
  407. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/android_sink.h +0 -0
  408. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/ansicolor_sink-inl.h +0 -0
  409. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/base_sink-inl.h +0 -0
  410. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/basic_file_sink-inl.h +0 -0
  411. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/basic_file_sink.h +0 -0
  412. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/dist_sink.h +0 -0
  413. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/dup_filter_sink.h +0 -0
  414. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/kafka_sink.h +0 -0
  415. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/mongo_sink.h +0 -0
  416. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/null_sink.h +0 -0
  417. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/ostream_sink.h +0 -0
  418. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/qt_sinks.h +0 -0
  419. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/ringbuffer_sink.h +0 -0
  420. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/rotating_file_sink.h +0 -0
  421. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/sink-inl.h +0 -0
  422. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/sink.h +0 -0
  423. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/stdout_color_sinks-inl.h +0 -0
  424. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/stdout_color_sinks.h +0 -0
  425. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/stdout_sinks-inl.h +0 -0
  426. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/stdout_sinks.h +0 -0
  427. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/systemd_sink.h +0 -0
  428. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/tcp_sink.h +0 -0
  429. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/udp_sink.h +0 -0
  430. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/win_eventlog_sink.h +0 -0
  431. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/sinks/wincolor_sink.h +0 -0
  432. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/spdlog-inl.h +0 -0
  433. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/spdlog.h +0 -0
  434. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/stopwatch.h +0 -0
  435. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/include/spdlog/tweakme.h +0 -0
  436. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/src/async.cpp +0 -0
  437. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/src/cfg.cpp +0 -0
  438. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/src/color_sinks.cpp +0 -0
  439. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/src/file_sinks.cpp +0 -0
  440. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/src/spdlog.cpp +0 -0
  441. /data/ext/cache/spdlog/{19df5d3d8e5526c255d27414e09568671ef87483 → 7251ead404dccd824789f8f3a13df2a6fb56440c}/spdlog/src/stdout_sinks.cpp +0 -0
@@ -1,2240 +0,0 @@
1
- // Formatting library for C++ - chrono support
2
- //
3
- // Copyright (c) 2012 - present, Victor Zverovich
4
- // All rights reserved.
5
- //
6
- // For the license information refer to format.h.
7
-
8
- #ifndef FMT_CHRONO_H_
9
- #define FMT_CHRONO_H_
10
-
11
- #include <algorithm>
12
- #include <chrono>
13
- #include <cmath> // std::isfinite
14
- #include <cstring> // std::memcpy
15
- #include <ctime>
16
- #include <iterator>
17
- #include <locale>
18
- #include <ostream>
19
- #include <type_traits>
20
-
21
- #include "ostream.h" // formatbuf
22
-
23
- FMT_BEGIN_NAMESPACE
24
-
25
- // Check if std::chrono::local_t is available.
26
- #ifndef FMT_USE_LOCAL_TIME
27
- # ifdef __cpp_lib_chrono
28
- # define FMT_USE_LOCAL_TIME (__cpp_lib_chrono >= 201907L)
29
- # else
30
- # define FMT_USE_LOCAL_TIME 0
31
- # endif
32
- #endif
33
-
34
- // Check if std::chrono::utc_timestamp is available.
35
- #ifndef FMT_USE_UTC_TIME
36
- # ifdef __cpp_lib_chrono
37
- # define FMT_USE_UTC_TIME (__cpp_lib_chrono >= 201907L)
38
- # else
39
- # define FMT_USE_UTC_TIME 0
40
- # endif
41
- #endif
42
-
43
- // Enable tzset.
44
- #ifndef FMT_USE_TZSET
45
- // UWP doesn't provide _tzset.
46
- # if FMT_HAS_INCLUDE("winapifamily.h")
47
- # include <winapifamily.h>
48
- # endif
49
- # if defined(_WIN32) && (!defined(WINAPI_FAMILY) || \
50
- (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
51
- # define FMT_USE_TZSET 1
52
- # else
53
- # define FMT_USE_TZSET 0
54
- # endif
55
- #endif
56
-
57
- // Enable safe chrono durations, unless explicitly disabled.
58
- #ifndef FMT_SAFE_DURATION_CAST
59
- # define FMT_SAFE_DURATION_CAST 1
60
- #endif
61
- #if FMT_SAFE_DURATION_CAST
62
-
63
- // For conversion between std::chrono::durations without undefined
64
- // behaviour or erroneous results.
65
- // This is a stripped down version of duration_cast, for inclusion in fmt.
66
- // See https://github.com/pauldreik/safe_duration_cast
67
- //
68
- // Copyright Paul Dreik 2019
69
- namespace safe_duration_cast {
70
-
71
- template <typename To, typename From,
72
- FMT_ENABLE_IF(!std::is_same<From, To>::value &&
73
- std::numeric_limits<From>::is_signed ==
74
- std::numeric_limits<To>::is_signed)>
75
- FMT_CONSTEXPR auto lossless_integral_conversion(const From from, int& ec)
76
- -> To {
77
- ec = 0;
78
- using F = std::numeric_limits<From>;
79
- using T = std::numeric_limits<To>;
80
- static_assert(F::is_integer, "From must be integral");
81
- static_assert(T::is_integer, "To must be integral");
82
-
83
- // A and B are both signed, or both unsigned.
84
- if (detail::const_check(F::digits <= T::digits)) {
85
- // From fits in To without any problem.
86
- } else {
87
- // From does not always fit in To, resort to a dynamic check.
88
- if (from < (T::min)() || from > (T::max)()) {
89
- // outside range.
90
- ec = 1;
91
- return {};
92
- }
93
- }
94
- return static_cast<To>(from);
95
- }
96
-
97
- /**
98
- * converts From to To, without loss. If the dynamic value of from
99
- * can't be converted to To without loss, ec is set.
100
- */
101
- template <typename To, typename From,
102
- FMT_ENABLE_IF(!std::is_same<From, To>::value &&
103
- std::numeric_limits<From>::is_signed !=
104
- std::numeric_limits<To>::is_signed)>
105
- FMT_CONSTEXPR auto lossless_integral_conversion(const From from, int& ec)
106
- -> To {
107
- ec = 0;
108
- using F = std::numeric_limits<From>;
109
- using T = std::numeric_limits<To>;
110
- static_assert(F::is_integer, "From must be integral");
111
- static_assert(T::is_integer, "To must be integral");
112
-
113
- if (detail::const_check(F::is_signed && !T::is_signed)) {
114
- // From may be negative, not allowed!
115
- if (fmt::detail::is_negative(from)) {
116
- ec = 1;
117
- return {};
118
- }
119
- // From is positive. Can it always fit in To?
120
- if (detail::const_check(F::digits > T::digits) &&
121
- from > static_cast<From>(detail::max_value<To>())) {
122
- ec = 1;
123
- return {};
124
- }
125
- }
126
-
127
- if (detail::const_check(!F::is_signed && T::is_signed &&
128
- F::digits >= T::digits) &&
129
- from > static_cast<From>(detail::max_value<To>())) {
130
- ec = 1;
131
- return {};
132
- }
133
- return static_cast<To>(from); // Lossless conversion.
134
- }
135
-
136
- template <typename To, typename From,
137
- FMT_ENABLE_IF(std::is_same<From, To>::value)>
138
- FMT_CONSTEXPR auto lossless_integral_conversion(const From from, int& ec)
139
- -> To {
140
- ec = 0;
141
- return from;
142
- } // function
143
-
144
- // clang-format off
145
- /**
146
- * converts From to To if possible, otherwise ec is set.
147
- *
148
- * input | output
149
- * ---------------------------------|---------------
150
- * NaN | NaN
151
- * Inf | Inf
152
- * normal, fits in output | converted (possibly lossy)
153
- * normal, does not fit in output | ec is set
154
- * subnormal | best effort
155
- * -Inf | -Inf
156
- */
157
- // clang-format on
158
- template <typename To, typename From,
159
- FMT_ENABLE_IF(!std::is_same<From, To>::value)>
160
- FMT_CONSTEXPR auto safe_float_conversion(const From from, int& ec) -> To {
161
- ec = 0;
162
- using T = std::numeric_limits<To>;
163
- static_assert(std::is_floating_point<From>::value, "From must be floating");
164
- static_assert(std::is_floating_point<To>::value, "To must be floating");
165
-
166
- // catch the only happy case
167
- if (std::isfinite(from)) {
168
- if (from >= T::lowest() && from <= (T::max)()) {
169
- return static_cast<To>(from);
170
- }
171
- // not within range.
172
- ec = 1;
173
- return {};
174
- }
175
-
176
- // nan and inf will be preserved
177
- return static_cast<To>(from);
178
- } // function
179
-
180
- template <typename To, typename From,
181
- FMT_ENABLE_IF(std::is_same<From, To>::value)>
182
- FMT_CONSTEXPR auto safe_float_conversion(const From from, int& ec) -> To {
183
- ec = 0;
184
- static_assert(std::is_floating_point<From>::value, "From must be floating");
185
- return from;
186
- }
187
-
188
- /**
189
- * safe duration cast between integral durations
190
- */
191
- template <typename To, typename FromRep, typename FromPeriod,
192
- FMT_ENABLE_IF(std::is_integral<FromRep>::value),
193
- FMT_ENABLE_IF(std::is_integral<typename To::rep>::value)>
194
- auto safe_duration_cast(std::chrono::duration<FromRep, FromPeriod> from,
195
- int& ec) -> To {
196
- using From = std::chrono::duration<FromRep, FromPeriod>;
197
- ec = 0;
198
- // the basic idea is that we need to convert from count() in the from type
199
- // to count() in the To type, by multiplying it with this:
200
- struct Factor
201
- : std::ratio_divide<typename From::period, typename To::period> {};
202
-
203
- static_assert(Factor::num > 0, "num must be positive");
204
- static_assert(Factor::den > 0, "den must be positive");
205
-
206
- // the conversion is like this: multiply from.count() with Factor::num
207
- // /Factor::den and convert it to To::rep, all this without
208
- // overflow/underflow. let's start by finding a suitable type that can hold
209
- // both To, From and Factor::num
210
- using IntermediateRep =
211
- typename std::common_type<typename From::rep, typename To::rep,
212
- decltype(Factor::num)>::type;
213
-
214
- // safe conversion to IntermediateRep
215
- IntermediateRep count =
216
- lossless_integral_conversion<IntermediateRep>(from.count(), ec);
217
- if (ec) return {};
218
- // multiply with Factor::num without overflow or underflow
219
- if (detail::const_check(Factor::num != 1)) {
220
- const auto max1 = detail::max_value<IntermediateRep>() / Factor::num;
221
- if (count > max1) {
222
- ec = 1;
223
- return {};
224
- }
225
- const auto min1 =
226
- (std::numeric_limits<IntermediateRep>::min)() / Factor::num;
227
- if (detail::const_check(!std::is_unsigned<IntermediateRep>::value) &&
228
- count < min1) {
229
- ec = 1;
230
- return {};
231
- }
232
- count *= Factor::num;
233
- }
234
-
235
- if (detail::const_check(Factor::den != 1)) count /= Factor::den;
236
- auto tocount = lossless_integral_conversion<typename To::rep>(count, ec);
237
- return ec ? To() : To(tocount);
238
- }
239
-
240
- /**
241
- * safe duration_cast between floating point durations
242
- */
243
- template <typename To, typename FromRep, typename FromPeriod,
244
- FMT_ENABLE_IF(std::is_floating_point<FromRep>::value),
245
- FMT_ENABLE_IF(std::is_floating_point<typename To::rep>::value)>
246
- auto safe_duration_cast(std::chrono::duration<FromRep, FromPeriod> from,
247
- int& ec) -> To {
248
- using From = std::chrono::duration<FromRep, FromPeriod>;
249
- ec = 0;
250
- if (std::isnan(from.count())) {
251
- // nan in, gives nan out. easy.
252
- return To{std::numeric_limits<typename To::rep>::quiet_NaN()};
253
- }
254
- // maybe we should also check if from is denormal, and decide what to do about
255
- // it.
256
-
257
- // +-inf should be preserved.
258
- if (std::isinf(from.count())) {
259
- return To{from.count()};
260
- }
261
-
262
- // the basic idea is that we need to convert from count() in the from type
263
- // to count() in the To type, by multiplying it with this:
264
- struct Factor
265
- : std::ratio_divide<typename From::period, typename To::period> {};
266
-
267
- static_assert(Factor::num > 0, "num must be positive");
268
- static_assert(Factor::den > 0, "den must be positive");
269
-
270
- // the conversion is like this: multiply from.count() with Factor::num
271
- // /Factor::den and convert it to To::rep, all this without
272
- // overflow/underflow. let's start by finding a suitable type that can hold
273
- // both To, From and Factor::num
274
- using IntermediateRep =
275
- typename std::common_type<typename From::rep, typename To::rep,
276
- decltype(Factor::num)>::type;
277
-
278
- // force conversion of From::rep -> IntermediateRep to be safe,
279
- // even if it will never happen be narrowing in this context.
280
- IntermediateRep count =
281
- safe_float_conversion<IntermediateRep>(from.count(), ec);
282
- if (ec) {
283
- return {};
284
- }
285
-
286
- // multiply with Factor::num without overflow or underflow
287
- if (detail::const_check(Factor::num != 1)) {
288
- constexpr auto max1 = detail::max_value<IntermediateRep>() /
289
- static_cast<IntermediateRep>(Factor::num);
290
- if (count > max1) {
291
- ec = 1;
292
- return {};
293
- }
294
- constexpr auto min1 = std::numeric_limits<IntermediateRep>::lowest() /
295
- static_cast<IntermediateRep>(Factor::num);
296
- if (count < min1) {
297
- ec = 1;
298
- return {};
299
- }
300
- count *= static_cast<IntermediateRep>(Factor::num);
301
- }
302
-
303
- // this can't go wrong, right? den>0 is checked earlier.
304
- if (detail::const_check(Factor::den != 1)) {
305
- using common_t = typename std::common_type<IntermediateRep, intmax_t>::type;
306
- count /= static_cast<common_t>(Factor::den);
307
- }
308
-
309
- // convert to the to type, safely
310
- using ToRep = typename To::rep;
311
-
312
- const ToRep tocount = safe_float_conversion<ToRep>(count, ec);
313
- if (ec) {
314
- return {};
315
- }
316
- return To{tocount};
317
- }
318
- } // namespace safe_duration_cast
319
- #endif
320
-
321
- // Prevents expansion of a preceding token as a function-style macro.
322
- // Usage: f FMT_NOMACRO()
323
- #define FMT_NOMACRO
324
-
325
- namespace detail {
326
- template <typename T = void> struct null {};
327
- inline auto localtime_r FMT_NOMACRO(...) -> null<> { return null<>(); }
328
- inline auto localtime_s(...) -> null<> { return null<>(); }
329
- inline auto gmtime_r(...) -> null<> { return null<>(); }
330
- inline auto gmtime_s(...) -> null<> { return null<>(); }
331
-
332
- inline auto get_classic_locale() -> const std::locale& {
333
- static const auto& locale = std::locale::classic();
334
- return locale;
335
- }
336
-
337
- template <typename CodeUnit> struct codecvt_result {
338
- static constexpr const size_t max_size = 32;
339
- CodeUnit buf[max_size];
340
- CodeUnit* end;
341
- };
342
-
343
- template <typename CodeUnit>
344
- void write_codecvt(codecvt_result<CodeUnit>& out, string_view in_buf,
345
- const std::locale& loc) {
346
- #if FMT_CLANG_VERSION
347
- # pragma clang diagnostic push
348
- # pragma clang diagnostic ignored "-Wdeprecated"
349
- auto& f = std::use_facet<std::codecvt<CodeUnit, char, std::mbstate_t>>(loc);
350
- # pragma clang diagnostic pop
351
- #else
352
- auto& f = std::use_facet<std::codecvt<CodeUnit, char, std::mbstate_t>>(loc);
353
- #endif
354
- auto mb = std::mbstate_t();
355
- const char* from_next = nullptr;
356
- auto result = f.in(mb, in_buf.begin(), in_buf.end(), from_next,
357
- std::begin(out.buf), std::end(out.buf), out.end);
358
- if (result != std::codecvt_base::ok)
359
- FMT_THROW(format_error("failed to format time"));
360
- }
361
-
362
- template <typename OutputIt>
363
- auto write_encoded_tm_str(OutputIt out, string_view in, const std::locale& loc)
364
- -> OutputIt {
365
- if (detail::is_utf8() && loc != get_classic_locale()) {
366
- // char16_t and char32_t codecvts are broken in MSVC (linkage errors) and
367
- // gcc-4.
368
- #if FMT_MSC_VERSION != 0 || \
369
- (defined(__GLIBCXX__) && !defined(_GLIBCXX_USE_DUAL_ABI))
370
- // The _GLIBCXX_USE_DUAL_ABI macro is always defined in libstdc++ from gcc-5
371
- // and newer.
372
- using code_unit = wchar_t;
373
- #else
374
- using code_unit = char32_t;
375
- #endif
376
-
377
- using unit_t = codecvt_result<code_unit>;
378
- unit_t unit;
379
- write_codecvt(unit, in, loc);
380
- // In UTF-8 is used one to four one-byte code units.
381
- auto u =
382
- to_utf8<code_unit, basic_memory_buffer<char, unit_t::max_size * 4>>();
383
- if (!u.convert({unit.buf, to_unsigned(unit.end - unit.buf)}))
384
- FMT_THROW(format_error("failed to format time"));
385
- return copy_str<char>(u.c_str(), u.c_str() + u.size(), out);
386
- }
387
- return copy_str<char>(in.data(), in.data() + in.size(), out);
388
- }
389
-
390
- template <typename Char, typename OutputIt,
391
- FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
392
- auto write_tm_str(OutputIt out, string_view sv, const std::locale& loc)
393
- -> OutputIt {
394
- codecvt_result<Char> unit;
395
- write_codecvt(unit, sv, loc);
396
- return copy_str<Char>(unit.buf, unit.end, out);
397
- }
398
-
399
- template <typename Char, typename OutputIt,
400
- FMT_ENABLE_IF(std::is_same<Char, char>::value)>
401
- auto write_tm_str(OutputIt out, string_view sv, const std::locale& loc)
402
- -> OutputIt {
403
- return write_encoded_tm_str(out, sv, loc);
404
- }
405
-
406
- template <typename Char>
407
- inline void do_write(buffer<Char>& buf, const std::tm& time,
408
- const std::locale& loc, char format, char modifier) {
409
- auto&& format_buf = formatbuf<std::basic_streambuf<Char>>(buf);
410
- auto&& os = std::basic_ostream<Char>(&format_buf);
411
- os.imbue(loc);
412
- const auto& facet = std::use_facet<std::time_put<Char>>(loc);
413
- auto end = facet.put(os, os, Char(' '), &time, format, modifier);
414
- if (end.failed()) FMT_THROW(format_error("failed to format time"));
415
- }
416
-
417
- template <typename Char, typename OutputIt,
418
- FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
419
- auto write(OutputIt out, const std::tm& time, const std::locale& loc,
420
- char format, char modifier = 0) -> OutputIt {
421
- auto&& buf = get_buffer<Char>(out);
422
- do_write<Char>(buf, time, loc, format, modifier);
423
- return get_iterator(buf, out);
424
- }
425
-
426
- template <typename Char, typename OutputIt,
427
- FMT_ENABLE_IF(std::is_same<Char, char>::value)>
428
- auto write(OutputIt out, const std::tm& time, const std::locale& loc,
429
- char format, char modifier = 0) -> OutputIt {
430
- auto&& buf = basic_memory_buffer<Char>();
431
- do_write<char>(buf, time, loc, format, modifier);
432
- return write_encoded_tm_str(out, string_view(buf.data(), buf.size()), loc);
433
- }
434
-
435
- template <typename Rep1, typename Rep2>
436
- struct is_same_arithmetic_type
437
- : public std::integral_constant<bool,
438
- (std::is_integral<Rep1>::value &&
439
- std::is_integral<Rep2>::value) ||
440
- (std::is_floating_point<Rep1>::value &&
441
- std::is_floating_point<Rep2>::value)> {
442
- };
443
-
444
- template <
445
- typename To, typename FromRep, typename FromPeriod,
446
- FMT_ENABLE_IF(is_same_arithmetic_type<FromRep, typename To::rep>::value)>
447
- auto fmt_duration_cast(std::chrono::duration<FromRep, FromPeriod> from) -> To {
448
- #if FMT_SAFE_DURATION_CAST
449
- // Throwing version of safe_duration_cast is only available for
450
- // integer to integer or float to float casts.
451
- int ec;
452
- To to = safe_duration_cast::safe_duration_cast<To>(from, ec);
453
- if (ec) FMT_THROW(format_error("cannot format duration"));
454
- return to;
455
- #else
456
- // Standard duration cast, may overflow.
457
- return std::chrono::duration_cast<To>(from);
458
- #endif
459
- }
460
-
461
- template <
462
- typename To, typename FromRep, typename FromPeriod,
463
- FMT_ENABLE_IF(!is_same_arithmetic_type<FromRep, typename To::rep>::value)>
464
- auto fmt_duration_cast(std::chrono::duration<FromRep, FromPeriod> from) -> To {
465
- // Mixed integer <-> float cast is not supported by safe_duration_cast.
466
- return std::chrono::duration_cast<To>(from);
467
- }
468
-
469
- template <typename Duration>
470
- auto to_time_t(
471
- std::chrono::time_point<std::chrono::system_clock, Duration> time_point)
472
- -> std::time_t {
473
- // Cannot use std::chrono::system_clock::to_time_t since this would first
474
- // require a cast to std::chrono::system_clock::time_point, which could
475
- // overflow.
476
- return fmt_duration_cast<std::chrono::duration<std::time_t>>(
477
- time_point.time_since_epoch())
478
- .count();
479
- }
480
- } // namespace detail
481
-
482
- FMT_BEGIN_EXPORT
483
-
484
- /**
485
- Converts given time since epoch as ``std::time_t`` value into calendar time,
486
- expressed in local time. Unlike ``std::localtime``, this function is
487
- thread-safe on most platforms.
488
- */
489
- inline auto localtime(std::time_t time) -> std::tm {
490
- struct dispatcher {
491
- std::time_t time_;
492
- std::tm tm_;
493
-
494
- dispatcher(std::time_t t) : time_(t) {}
495
-
496
- auto run() -> bool {
497
- using namespace fmt::detail;
498
- return handle(localtime_r(&time_, &tm_));
499
- }
500
-
501
- auto handle(std::tm* tm) -> bool { return tm != nullptr; }
502
-
503
- auto handle(detail::null<>) -> bool {
504
- using namespace fmt::detail;
505
- return fallback(localtime_s(&tm_, &time_));
506
- }
507
-
508
- auto fallback(int res) -> bool { return res == 0; }
509
-
510
- #if !FMT_MSC_VERSION
511
- auto fallback(detail::null<>) -> bool {
512
- using namespace fmt::detail;
513
- std::tm* tm = std::localtime(&time_);
514
- if (tm) tm_ = *tm;
515
- return tm != nullptr;
516
- }
517
- #endif
518
- };
519
- dispatcher lt(time);
520
- // Too big time values may be unsupported.
521
- if (!lt.run()) FMT_THROW(format_error("time_t value out of range"));
522
- return lt.tm_;
523
- }
524
-
525
- #if FMT_USE_LOCAL_TIME
526
- template <typename Duration>
527
- inline auto localtime(std::chrono::local_time<Duration> time) -> std::tm {
528
- return localtime(
529
- detail::to_time_t(std::chrono::current_zone()->to_sys(time)));
530
- }
531
- #endif
532
-
533
- /**
534
- Converts given time since epoch as ``std::time_t`` value into calendar time,
535
- expressed in Coordinated Universal Time (UTC). Unlike ``std::gmtime``, this
536
- function is thread-safe on most platforms.
537
- */
538
- inline auto gmtime(std::time_t time) -> std::tm {
539
- struct dispatcher {
540
- std::time_t time_;
541
- std::tm tm_;
542
-
543
- dispatcher(std::time_t t) : time_(t) {}
544
-
545
- auto run() -> bool {
546
- using namespace fmt::detail;
547
- return handle(gmtime_r(&time_, &tm_));
548
- }
549
-
550
- auto handle(std::tm* tm) -> bool { return tm != nullptr; }
551
-
552
- auto handle(detail::null<>) -> bool {
553
- using namespace fmt::detail;
554
- return fallback(gmtime_s(&tm_, &time_));
555
- }
556
-
557
- auto fallback(int res) -> bool { return res == 0; }
558
-
559
- #if !FMT_MSC_VERSION
560
- auto fallback(detail::null<>) -> bool {
561
- std::tm* tm = std::gmtime(&time_);
562
- if (tm) tm_ = *tm;
563
- return tm != nullptr;
564
- }
565
- #endif
566
- };
567
- auto gt = dispatcher(time);
568
- // Too big time values may be unsupported.
569
- if (!gt.run()) FMT_THROW(format_error("time_t value out of range"));
570
- return gt.tm_;
571
- }
572
-
573
- template <typename Duration>
574
- inline auto gmtime(
575
- std::chrono::time_point<std::chrono::system_clock, Duration> time_point)
576
- -> std::tm {
577
- return gmtime(detail::to_time_t(time_point));
578
- }
579
-
580
- namespace detail {
581
-
582
- // Writes two-digit numbers a, b and c separated by sep to buf.
583
- // The method by Pavel Novikov based on
584
- // https://johnnylee-sde.github.io/Fast-unsigned-integer-to-time-string/.
585
- inline void write_digit2_separated(char* buf, unsigned a, unsigned b,
586
- unsigned c, char sep) {
587
- unsigned long long digits =
588
- a | (b << 24) | (static_cast<unsigned long long>(c) << 48);
589
- // Convert each value to BCD.
590
- // We have x = a * 10 + b and we want to convert it to BCD y = a * 16 + b.
591
- // The difference is
592
- // y - x = a * 6
593
- // a can be found from x:
594
- // a = floor(x / 10)
595
- // then
596
- // y = x + a * 6 = x + floor(x / 10) * 6
597
- // floor(x / 10) is (x * 205) >> 11 (needs 16 bits).
598
- digits += (((digits * 205) >> 11) & 0x000f00000f00000f) * 6;
599
- // Put low nibbles to high bytes and high nibbles to low bytes.
600
- digits = ((digits & 0x00f00000f00000f0) >> 4) |
601
- ((digits & 0x000f00000f00000f) << 8);
602
- auto usep = static_cast<unsigned long long>(sep);
603
- // Add ASCII '0' to each digit byte and insert separators.
604
- digits |= 0x3030003030003030 | (usep << 16) | (usep << 40);
605
-
606
- constexpr const size_t len = 8;
607
- if (const_check(is_big_endian())) {
608
- char tmp[len];
609
- std::memcpy(tmp, &digits, len);
610
- std::reverse_copy(tmp, tmp + len, buf);
611
- } else {
612
- std::memcpy(buf, &digits, len);
613
- }
614
- }
615
-
616
- template <typename Period>
617
- FMT_CONSTEXPR inline auto get_units() -> const char* {
618
- if (std::is_same<Period, std::atto>::value) return "as";
619
- if (std::is_same<Period, std::femto>::value) return "fs";
620
- if (std::is_same<Period, std::pico>::value) return "ps";
621
- if (std::is_same<Period, std::nano>::value) return "ns";
622
- if (std::is_same<Period, std::micro>::value) return "µs";
623
- if (std::is_same<Period, std::milli>::value) return "ms";
624
- if (std::is_same<Period, std::centi>::value) return "cs";
625
- if (std::is_same<Period, std::deci>::value) return "ds";
626
- if (std::is_same<Period, std::ratio<1>>::value) return "s";
627
- if (std::is_same<Period, std::deca>::value) return "das";
628
- if (std::is_same<Period, std::hecto>::value) return "hs";
629
- if (std::is_same<Period, std::kilo>::value) return "ks";
630
- if (std::is_same<Period, std::mega>::value) return "Ms";
631
- if (std::is_same<Period, std::giga>::value) return "Gs";
632
- if (std::is_same<Period, std::tera>::value) return "Ts";
633
- if (std::is_same<Period, std::peta>::value) return "Ps";
634
- if (std::is_same<Period, std::exa>::value) return "Es";
635
- if (std::is_same<Period, std::ratio<60>>::value) return "min";
636
- if (std::is_same<Period, std::ratio<3600>>::value) return "h";
637
- if (std::is_same<Period, std::ratio<86400>>::value) return "d";
638
- return nullptr;
639
- }
640
-
641
- enum class numeric_system {
642
- standard,
643
- // Alternative numeric system, e.g. 十二 instead of 12 in ja_JP locale.
644
- alternative
645
- };
646
-
647
- // Glibc extensions for formatting numeric values.
648
- enum class pad_type {
649
- unspecified,
650
- // Do not pad a numeric result string.
651
- none,
652
- // Pad a numeric result string with zeros even if the conversion specifier
653
- // character uses space-padding by default.
654
- zero,
655
- // Pad a numeric result string with spaces.
656
- space,
657
- };
658
-
659
- template <typename OutputIt>
660
- auto write_padding(OutputIt out, pad_type pad, int width) -> OutputIt {
661
- if (pad == pad_type::none) return out;
662
- return std::fill_n(out, width, pad == pad_type::space ? ' ' : '0');
663
- }
664
-
665
- template <typename OutputIt>
666
- auto write_padding(OutputIt out, pad_type pad) -> OutputIt {
667
- if (pad != pad_type::none) *out++ = pad == pad_type::space ? ' ' : '0';
668
- return out;
669
- }
670
-
671
- // Parses a put_time-like format string and invokes handler actions.
672
- template <typename Char, typename Handler>
673
- FMT_CONSTEXPR auto parse_chrono_format(const Char* begin, const Char* end,
674
- Handler&& handler) -> const Char* {
675
- if (begin == end || *begin == '}') return begin;
676
- if (*begin != '%') FMT_THROW(format_error("invalid format"));
677
- auto ptr = begin;
678
- pad_type pad = pad_type::unspecified;
679
- while (ptr != end) {
680
- auto c = *ptr;
681
- if (c == '}') break;
682
- if (c != '%') {
683
- ++ptr;
684
- continue;
685
- }
686
- if (begin != ptr) handler.on_text(begin, ptr);
687
- ++ptr; // consume '%'
688
- if (ptr == end) FMT_THROW(format_error("invalid format"));
689
- c = *ptr;
690
- switch (c) {
691
- case '_':
692
- pad = pad_type::space;
693
- ++ptr;
694
- break;
695
- case '-':
696
- pad = pad_type::none;
697
- ++ptr;
698
- break;
699
- case '0':
700
- pad = pad_type::zero;
701
- ++ptr;
702
- break;
703
- }
704
- if (ptr == end) FMT_THROW(format_error("invalid format"));
705
- c = *ptr++;
706
- switch (c) {
707
- case '%':
708
- handler.on_text(ptr - 1, ptr);
709
- break;
710
- case 'n': {
711
- const Char newline[] = {'\n'};
712
- handler.on_text(newline, newline + 1);
713
- break;
714
- }
715
- case 't': {
716
- const Char tab[] = {'\t'};
717
- handler.on_text(tab, tab + 1);
718
- break;
719
- }
720
- // Year:
721
- case 'Y':
722
- handler.on_year(numeric_system::standard);
723
- break;
724
- case 'y':
725
- handler.on_short_year(numeric_system::standard);
726
- break;
727
- case 'C':
728
- handler.on_century(numeric_system::standard);
729
- break;
730
- case 'G':
731
- handler.on_iso_week_based_year();
732
- break;
733
- case 'g':
734
- handler.on_iso_week_based_short_year();
735
- break;
736
- // Day of the week:
737
- case 'a':
738
- handler.on_abbr_weekday();
739
- break;
740
- case 'A':
741
- handler.on_full_weekday();
742
- break;
743
- case 'w':
744
- handler.on_dec0_weekday(numeric_system::standard);
745
- break;
746
- case 'u':
747
- handler.on_dec1_weekday(numeric_system::standard);
748
- break;
749
- // Month:
750
- case 'b':
751
- case 'h':
752
- handler.on_abbr_month();
753
- break;
754
- case 'B':
755
- handler.on_full_month();
756
- break;
757
- case 'm':
758
- handler.on_dec_month(numeric_system::standard);
759
- break;
760
- // Day of the year/month:
761
- case 'U':
762
- handler.on_dec0_week_of_year(numeric_system::standard);
763
- break;
764
- case 'W':
765
- handler.on_dec1_week_of_year(numeric_system::standard);
766
- break;
767
- case 'V':
768
- handler.on_iso_week_of_year(numeric_system::standard);
769
- break;
770
- case 'j':
771
- handler.on_day_of_year();
772
- break;
773
- case 'd':
774
- handler.on_day_of_month(numeric_system::standard);
775
- break;
776
- case 'e':
777
- handler.on_day_of_month_space(numeric_system::standard);
778
- break;
779
- // Hour, minute, second:
780
- case 'H':
781
- handler.on_24_hour(numeric_system::standard, pad);
782
- break;
783
- case 'I':
784
- handler.on_12_hour(numeric_system::standard, pad);
785
- break;
786
- case 'M':
787
- handler.on_minute(numeric_system::standard, pad);
788
- break;
789
- case 'S':
790
- handler.on_second(numeric_system::standard, pad);
791
- break;
792
- // Other:
793
- case 'c':
794
- handler.on_datetime(numeric_system::standard);
795
- break;
796
- case 'x':
797
- handler.on_loc_date(numeric_system::standard);
798
- break;
799
- case 'X':
800
- handler.on_loc_time(numeric_system::standard);
801
- break;
802
- case 'D':
803
- handler.on_us_date();
804
- break;
805
- case 'F':
806
- handler.on_iso_date();
807
- break;
808
- case 'r':
809
- handler.on_12_hour_time();
810
- break;
811
- case 'R':
812
- handler.on_24_hour_time();
813
- break;
814
- case 'T':
815
- handler.on_iso_time();
816
- break;
817
- case 'p':
818
- handler.on_am_pm();
819
- break;
820
- case 'Q':
821
- handler.on_duration_value();
822
- break;
823
- case 'q':
824
- handler.on_duration_unit();
825
- break;
826
- case 'z':
827
- handler.on_utc_offset(numeric_system::standard);
828
- break;
829
- case 'Z':
830
- handler.on_tz_name();
831
- break;
832
- // Alternative representation:
833
- case 'E': {
834
- if (ptr == end) FMT_THROW(format_error("invalid format"));
835
- c = *ptr++;
836
- switch (c) {
837
- case 'Y':
838
- handler.on_year(numeric_system::alternative);
839
- break;
840
- case 'y':
841
- handler.on_offset_year();
842
- break;
843
- case 'C':
844
- handler.on_century(numeric_system::alternative);
845
- break;
846
- case 'c':
847
- handler.on_datetime(numeric_system::alternative);
848
- break;
849
- case 'x':
850
- handler.on_loc_date(numeric_system::alternative);
851
- break;
852
- case 'X':
853
- handler.on_loc_time(numeric_system::alternative);
854
- break;
855
- case 'z':
856
- handler.on_utc_offset(numeric_system::alternative);
857
- break;
858
- default:
859
- FMT_THROW(format_error("invalid format"));
860
- }
861
- break;
862
- }
863
- case 'O':
864
- if (ptr == end) FMT_THROW(format_error("invalid format"));
865
- c = *ptr++;
866
- switch (c) {
867
- case 'y':
868
- handler.on_short_year(numeric_system::alternative);
869
- break;
870
- case 'm':
871
- handler.on_dec_month(numeric_system::alternative);
872
- break;
873
- case 'U':
874
- handler.on_dec0_week_of_year(numeric_system::alternative);
875
- break;
876
- case 'W':
877
- handler.on_dec1_week_of_year(numeric_system::alternative);
878
- break;
879
- case 'V':
880
- handler.on_iso_week_of_year(numeric_system::alternative);
881
- break;
882
- case 'd':
883
- handler.on_day_of_month(numeric_system::alternative);
884
- break;
885
- case 'e':
886
- handler.on_day_of_month_space(numeric_system::alternative);
887
- break;
888
- case 'w':
889
- handler.on_dec0_weekday(numeric_system::alternative);
890
- break;
891
- case 'u':
892
- handler.on_dec1_weekday(numeric_system::alternative);
893
- break;
894
- case 'H':
895
- handler.on_24_hour(numeric_system::alternative, pad);
896
- break;
897
- case 'I':
898
- handler.on_12_hour(numeric_system::alternative, pad);
899
- break;
900
- case 'M':
901
- handler.on_minute(numeric_system::alternative, pad);
902
- break;
903
- case 'S':
904
- handler.on_second(numeric_system::alternative, pad);
905
- break;
906
- case 'z':
907
- handler.on_utc_offset(numeric_system::alternative);
908
- break;
909
- default:
910
- FMT_THROW(format_error("invalid format"));
911
- }
912
- break;
913
- default:
914
- FMT_THROW(format_error("invalid format"));
915
- }
916
- begin = ptr;
917
- }
918
- if (begin != ptr) handler.on_text(begin, ptr);
919
- return ptr;
920
- }
921
-
922
- template <typename Derived> struct null_chrono_spec_handler {
923
- FMT_CONSTEXPR void unsupported() {
924
- static_cast<Derived*>(this)->unsupported();
925
- }
926
- FMT_CONSTEXPR void on_year(numeric_system) { unsupported(); }
927
- FMT_CONSTEXPR void on_short_year(numeric_system) { unsupported(); }
928
- FMT_CONSTEXPR void on_offset_year() { unsupported(); }
929
- FMT_CONSTEXPR void on_century(numeric_system) { unsupported(); }
930
- FMT_CONSTEXPR void on_iso_week_based_year() { unsupported(); }
931
- FMT_CONSTEXPR void on_iso_week_based_short_year() { unsupported(); }
932
- FMT_CONSTEXPR void on_abbr_weekday() { unsupported(); }
933
- FMT_CONSTEXPR void on_full_weekday() { unsupported(); }
934
- FMT_CONSTEXPR void on_dec0_weekday(numeric_system) { unsupported(); }
935
- FMT_CONSTEXPR void on_dec1_weekday(numeric_system) { unsupported(); }
936
- FMT_CONSTEXPR void on_abbr_month() { unsupported(); }
937
- FMT_CONSTEXPR void on_full_month() { unsupported(); }
938
- FMT_CONSTEXPR void on_dec_month(numeric_system) { unsupported(); }
939
- FMT_CONSTEXPR void on_dec0_week_of_year(numeric_system) { unsupported(); }
940
- FMT_CONSTEXPR void on_dec1_week_of_year(numeric_system) { unsupported(); }
941
- FMT_CONSTEXPR void on_iso_week_of_year(numeric_system) { unsupported(); }
942
- FMT_CONSTEXPR void on_day_of_year() { unsupported(); }
943
- FMT_CONSTEXPR void on_day_of_month(numeric_system) { unsupported(); }
944
- FMT_CONSTEXPR void on_day_of_month_space(numeric_system) { unsupported(); }
945
- FMT_CONSTEXPR void on_24_hour(numeric_system) { unsupported(); }
946
- FMT_CONSTEXPR void on_12_hour(numeric_system) { unsupported(); }
947
- FMT_CONSTEXPR void on_minute(numeric_system) { unsupported(); }
948
- FMT_CONSTEXPR void on_second(numeric_system) { unsupported(); }
949
- FMT_CONSTEXPR void on_datetime(numeric_system) { unsupported(); }
950
- FMT_CONSTEXPR void on_loc_date(numeric_system) { unsupported(); }
951
- FMT_CONSTEXPR void on_loc_time(numeric_system) { unsupported(); }
952
- FMT_CONSTEXPR void on_us_date() { unsupported(); }
953
- FMT_CONSTEXPR void on_iso_date() { unsupported(); }
954
- FMT_CONSTEXPR void on_12_hour_time() { unsupported(); }
955
- FMT_CONSTEXPR void on_24_hour_time() { unsupported(); }
956
- FMT_CONSTEXPR void on_iso_time() { unsupported(); }
957
- FMT_CONSTEXPR void on_am_pm() { unsupported(); }
958
- FMT_CONSTEXPR void on_duration_value() { unsupported(); }
959
- FMT_CONSTEXPR void on_duration_unit() { unsupported(); }
960
- FMT_CONSTEXPR void on_utc_offset(numeric_system) { unsupported(); }
961
- FMT_CONSTEXPR void on_tz_name() { unsupported(); }
962
- };
963
-
964
- struct tm_format_checker : null_chrono_spec_handler<tm_format_checker> {
965
- FMT_NORETURN void unsupported() { FMT_THROW(format_error("no format")); }
966
-
967
- template <typename Char>
968
- FMT_CONSTEXPR void on_text(const Char*, const Char*) {}
969
- FMT_CONSTEXPR void on_year(numeric_system) {}
970
- FMT_CONSTEXPR void on_short_year(numeric_system) {}
971
- FMT_CONSTEXPR void on_offset_year() {}
972
- FMT_CONSTEXPR void on_century(numeric_system) {}
973
- FMT_CONSTEXPR void on_iso_week_based_year() {}
974
- FMT_CONSTEXPR void on_iso_week_based_short_year() {}
975
- FMT_CONSTEXPR void on_abbr_weekday() {}
976
- FMT_CONSTEXPR void on_full_weekday() {}
977
- FMT_CONSTEXPR void on_dec0_weekday(numeric_system) {}
978
- FMT_CONSTEXPR void on_dec1_weekday(numeric_system) {}
979
- FMT_CONSTEXPR void on_abbr_month() {}
980
- FMT_CONSTEXPR void on_full_month() {}
981
- FMT_CONSTEXPR void on_dec_month(numeric_system) {}
982
- FMT_CONSTEXPR void on_dec0_week_of_year(numeric_system) {}
983
- FMT_CONSTEXPR void on_dec1_week_of_year(numeric_system) {}
984
- FMT_CONSTEXPR void on_iso_week_of_year(numeric_system) {}
985
- FMT_CONSTEXPR void on_day_of_year() {}
986
- FMT_CONSTEXPR void on_day_of_month(numeric_system) {}
987
- FMT_CONSTEXPR void on_day_of_month_space(numeric_system) {}
988
- FMT_CONSTEXPR void on_24_hour(numeric_system, pad_type) {}
989
- FMT_CONSTEXPR void on_12_hour(numeric_system, pad_type) {}
990
- FMT_CONSTEXPR void on_minute(numeric_system, pad_type) {}
991
- FMT_CONSTEXPR void on_second(numeric_system, pad_type) {}
992
- FMT_CONSTEXPR void on_datetime(numeric_system) {}
993
- FMT_CONSTEXPR void on_loc_date(numeric_system) {}
994
- FMT_CONSTEXPR void on_loc_time(numeric_system) {}
995
- FMT_CONSTEXPR void on_us_date() {}
996
- FMT_CONSTEXPR void on_iso_date() {}
997
- FMT_CONSTEXPR void on_12_hour_time() {}
998
- FMT_CONSTEXPR void on_24_hour_time() {}
999
- FMT_CONSTEXPR void on_iso_time() {}
1000
- FMT_CONSTEXPR void on_am_pm() {}
1001
- FMT_CONSTEXPR void on_utc_offset(numeric_system) {}
1002
- FMT_CONSTEXPR void on_tz_name() {}
1003
- };
1004
-
1005
- inline auto tm_wday_full_name(int wday) -> const char* {
1006
- static constexpr const char* full_name_list[] = {
1007
- "Sunday", "Monday", "Tuesday", "Wednesday",
1008
- "Thursday", "Friday", "Saturday"};
1009
- return wday >= 0 && wday <= 6 ? full_name_list[wday] : "?";
1010
- }
1011
- inline auto tm_wday_short_name(int wday) -> const char* {
1012
- static constexpr const char* short_name_list[] = {"Sun", "Mon", "Tue", "Wed",
1013
- "Thu", "Fri", "Sat"};
1014
- return wday >= 0 && wday <= 6 ? short_name_list[wday] : "???";
1015
- }
1016
-
1017
- inline auto tm_mon_full_name(int mon) -> const char* {
1018
- static constexpr const char* full_name_list[] = {
1019
- "January", "February", "March", "April", "May", "June",
1020
- "July", "August", "September", "October", "November", "December"};
1021
- return mon >= 0 && mon <= 11 ? full_name_list[mon] : "?";
1022
- }
1023
- inline auto tm_mon_short_name(int mon) -> const char* {
1024
- static constexpr const char* short_name_list[] = {
1025
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
1026
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
1027
- };
1028
- return mon >= 0 && mon <= 11 ? short_name_list[mon] : "???";
1029
- }
1030
-
1031
- template <typename T, typename = void>
1032
- struct has_member_data_tm_gmtoff : std::false_type {};
1033
- template <typename T>
1034
- struct has_member_data_tm_gmtoff<T, void_t<decltype(T::tm_gmtoff)>>
1035
- : std::true_type {};
1036
-
1037
- template <typename T, typename = void>
1038
- struct has_member_data_tm_zone : std::false_type {};
1039
- template <typename T>
1040
- struct has_member_data_tm_zone<T, void_t<decltype(T::tm_zone)>>
1041
- : std::true_type {};
1042
-
1043
- #if FMT_USE_TZSET
1044
- inline void tzset_once() {
1045
- static bool init = []() -> bool {
1046
- _tzset();
1047
- return true;
1048
- }();
1049
- ignore_unused(init);
1050
- }
1051
- #endif
1052
-
1053
- // Converts value to Int and checks that it's in the range [0, upper).
1054
- template <typename T, typename Int, FMT_ENABLE_IF(std::is_integral<T>::value)>
1055
- inline auto to_nonnegative_int(T value, Int upper) -> Int {
1056
- if (!std::is_unsigned<Int>::value &&
1057
- (value < 0 || to_unsigned(value) > to_unsigned(upper))) {
1058
- FMT_THROW(fmt::format_error("chrono value is out of range"));
1059
- }
1060
- return static_cast<Int>(value);
1061
- }
1062
- template <typename T, typename Int, FMT_ENABLE_IF(!std::is_integral<T>::value)>
1063
- inline auto to_nonnegative_int(T value, Int upper) -> Int {
1064
- if (value < 0 || value > static_cast<T>(upper))
1065
- FMT_THROW(format_error("invalid value"));
1066
- return static_cast<Int>(value);
1067
- }
1068
-
1069
- constexpr auto pow10(std::uint32_t n) -> long long {
1070
- return n == 0 ? 1 : 10 * pow10(n - 1);
1071
- }
1072
-
1073
- // Counts the number of fractional digits in the range [0, 18] according to the
1074
- // C++20 spec. If more than 18 fractional digits are required then returns 6 for
1075
- // microseconds precision.
1076
- template <long long Num, long long Den, int N = 0,
1077
- bool Enabled = (N < 19) && (Num <= max_value<long long>() / 10)>
1078
- struct count_fractional_digits {
1079
- static constexpr int value =
1080
- Num % Den == 0 ? N : count_fractional_digits<Num * 10, Den, N + 1>::value;
1081
- };
1082
-
1083
- // Base case that doesn't instantiate any more templates
1084
- // in order to avoid overflow.
1085
- template <long long Num, long long Den, int N>
1086
- struct count_fractional_digits<Num, Den, N, false> {
1087
- static constexpr int value = (Num % Den == 0) ? N : 6;
1088
- };
1089
-
1090
- // Format subseconds which are given as an integer type with an appropriate
1091
- // number of digits.
1092
- template <typename Char, typename OutputIt, typename Duration>
1093
- void write_fractional_seconds(OutputIt& out, Duration d, int precision = -1) {
1094
- constexpr auto num_fractional_digits =
1095
- count_fractional_digits<Duration::period::num,
1096
- Duration::period::den>::value;
1097
-
1098
- using subsecond_precision = std::chrono::duration<
1099
- typename std::common_type<typename Duration::rep,
1100
- std::chrono::seconds::rep>::type,
1101
- std::ratio<1, detail::pow10(num_fractional_digits)>>;
1102
-
1103
- const auto fractional = d - fmt_duration_cast<std::chrono::seconds>(d);
1104
- const auto subseconds =
1105
- std::chrono::treat_as_floating_point<
1106
- typename subsecond_precision::rep>::value
1107
- ? fractional.count()
1108
- : fmt_duration_cast<subsecond_precision>(fractional).count();
1109
- auto n = static_cast<uint32_or_64_or_128_t<long long>>(subseconds);
1110
- const int num_digits = detail::count_digits(n);
1111
-
1112
- int leading_zeroes = (std::max)(0, num_fractional_digits - num_digits);
1113
- if (precision < 0) {
1114
- FMT_ASSERT(!std::is_floating_point<typename Duration::rep>::value, "");
1115
- if (std::ratio_less<typename subsecond_precision::period,
1116
- std::chrono::seconds::period>::value) {
1117
- *out++ = '.';
1118
- out = std::fill_n(out, leading_zeroes, '0');
1119
- out = format_decimal<Char>(out, n, num_digits).end;
1120
- }
1121
- } else {
1122
- *out++ = '.';
1123
- leading_zeroes = (std::min)(leading_zeroes, precision);
1124
- out = std::fill_n(out, leading_zeroes, '0');
1125
- int remaining = precision - leading_zeroes;
1126
- if (remaining != 0 && remaining < num_digits) {
1127
- n /= to_unsigned(detail::pow10(to_unsigned(num_digits - remaining)));
1128
- out = format_decimal<Char>(out, n, remaining).end;
1129
- return;
1130
- }
1131
- out = format_decimal<Char>(out, n, num_digits).end;
1132
- remaining -= num_digits;
1133
- out = std::fill_n(out, remaining, '0');
1134
- }
1135
- }
1136
-
1137
- // Format subseconds which are given as a floating point type with an
1138
- // appropriate number of digits. We cannot pass the Duration here, as we
1139
- // explicitly need to pass the Rep value in the chrono_formatter.
1140
- template <typename Duration>
1141
- void write_floating_seconds(memory_buffer& buf, Duration duration,
1142
- int num_fractional_digits = -1) {
1143
- using rep = typename Duration::rep;
1144
- FMT_ASSERT(std::is_floating_point<rep>::value, "");
1145
-
1146
- auto val = duration.count();
1147
-
1148
- if (num_fractional_digits < 0) {
1149
- // For `std::round` with fallback to `round`:
1150
- // On some toolchains `std::round` is not available (e.g. GCC 6).
1151
- using namespace std;
1152
- num_fractional_digits =
1153
- count_fractional_digits<Duration::period::num,
1154
- Duration::period::den>::value;
1155
- if (num_fractional_digits < 6 && static_cast<rep>(round(val)) != val)
1156
- num_fractional_digits = 6;
1157
- }
1158
-
1159
- fmt::format_to(std::back_inserter(buf), FMT_STRING("{:.{}f}"),
1160
- std::fmod(val * static_cast<rep>(Duration::period::num) /
1161
- static_cast<rep>(Duration::period::den),
1162
- static_cast<rep>(60)),
1163
- num_fractional_digits);
1164
- }
1165
-
1166
- template <typename OutputIt, typename Char,
1167
- typename Duration = std::chrono::seconds>
1168
- class tm_writer {
1169
- private:
1170
- static constexpr int days_per_week = 7;
1171
-
1172
- const std::locale& loc_;
1173
- const bool is_classic_;
1174
- OutputIt out_;
1175
- const Duration* subsecs_;
1176
- const std::tm& tm_;
1177
-
1178
- auto tm_sec() const noexcept -> int {
1179
- FMT_ASSERT(tm_.tm_sec >= 0 && tm_.tm_sec <= 61, "");
1180
- return tm_.tm_sec;
1181
- }
1182
- auto tm_min() const noexcept -> int {
1183
- FMT_ASSERT(tm_.tm_min >= 0 && tm_.tm_min <= 59, "");
1184
- return tm_.tm_min;
1185
- }
1186
- auto tm_hour() const noexcept -> int {
1187
- FMT_ASSERT(tm_.tm_hour >= 0 && tm_.tm_hour <= 23, "");
1188
- return tm_.tm_hour;
1189
- }
1190
- auto tm_mday() const noexcept -> int {
1191
- FMT_ASSERT(tm_.tm_mday >= 1 && tm_.tm_mday <= 31, "");
1192
- return tm_.tm_mday;
1193
- }
1194
- auto tm_mon() const noexcept -> int {
1195
- FMT_ASSERT(tm_.tm_mon >= 0 && tm_.tm_mon <= 11, "");
1196
- return tm_.tm_mon;
1197
- }
1198
- auto tm_year() const noexcept -> long long { return 1900ll + tm_.tm_year; }
1199
- auto tm_wday() const noexcept -> int {
1200
- FMT_ASSERT(tm_.tm_wday >= 0 && tm_.tm_wday <= 6, "");
1201
- return tm_.tm_wday;
1202
- }
1203
- auto tm_yday() const noexcept -> int {
1204
- FMT_ASSERT(tm_.tm_yday >= 0 && tm_.tm_yday <= 365, "");
1205
- return tm_.tm_yday;
1206
- }
1207
-
1208
- auto tm_hour12() const noexcept -> int {
1209
- const auto h = tm_hour();
1210
- const auto z = h < 12 ? h : h - 12;
1211
- return z == 0 ? 12 : z;
1212
- }
1213
-
1214
- // POSIX and the C Standard are unclear or inconsistent about what %C and %y
1215
- // do if the year is negative or exceeds 9999. Use the convention that %C
1216
- // concatenated with %y yields the same output as %Y, and that %Y contains at
1217
- // least 4 characters, with more only if necessary.
1218
- auto split_year_lower(long long year) const noexcept -> int {
1219
- auto l = year % 100;
1220
- if (l < 0) l = -l; // l in [0, 99]
1221
- return static_cast<int>(l);
1222
- }
1223
-
1224
- // Algorithm: https://en.wikipedia.org/wiki/ISO_week_date.
1225
- auto iso_year_weeks(long long curr_year) const noexcept -> int {
1226
- const auto prev_year = curr_year - 1;
1227
- const auto curr_p =
1228
- (curr_year + curr_year / 4 - curr_year / 100 + curr_year / 400) %
1229
- days_per_week;
1230
- const auto prev_p =
1231
- (prev_year + prev_year / 4 - prev_year / 100 + prev_year / 400) %
1232
- days_per_week;
1233
- return 52 + ((curr_p == 4 || prev_p == 3) ? 1 : 0);
1234
- }
1235
- auto iso_week_num(int tm_yday, int tm_wday) const noexcept -> int {
1236
- return (tm_yday + 11 - (tm_wday == 0 ? days_per_week : tm_wday)) /
1237
- days_per_week;
1238
- }
1239
- auto tm_iso_week_year() const noexcept -> long long {
1240
- const auto year = tm_year();
1241
- const auto w = iso_week_num(tm_yday(), tm_wday());
1242
- if (w < 1) return year - 1;
1243
- if (w > iso_year_weeks(year)) return year + 1;
1244
- return year;
1245
- }
1246
- auto tm_iso_week_of_year() const noexcept -> int {
1247
- const auto year = tm_year();
1248
- const auto w = iso_week_num(tm_yday(), tm_wday());
1249
- if (w < 1) return iso_year_weeks(year - 1);
1250
- if (w > iso_year_weeks(year)) return 1;
1251
- return w;
1252
- }
1253
-
1254
- void write1(int value) {
1255
- *out_++ = static_cast<char>('0' + to_unsigned(value) % 10);
1256
- }
1257
- void write2(int value) {
1258
- const char* d = digits2(to_unsigned(value) % 100);
1259
- *out_++ = *d++;
1260
- *out_++ = *d;
1261
- }
1262
- void write2(int value, pad_type pad) {
1263
- unsigned int v = to_unsigned(value) % 100;
1264
- if (v >= 10) {
1265
- const char* d = digits2(v);
1266
- *out_++ = *d++;
1267
- *out_++ = *d;
1268
- } else {
1269
- out_ = detail::write_padding(out_, pad);
1270
- *out_++ = static_cast<char>('0' + v);
1271
- }
1272
- }
1273
-
1274
- void write_year_extended(long long year) {
1275
- // At least 4 characters.
1276
- int width = 4;
1277
- if (year < 0) {
1278
- *out_++ = '-';
1279
- year = 0 - year;
1280
- --width;
1281
- }
1282
- uint32_or_64_or_128_t<long long> n = to_unsigned(year);
1283
- const int num_digits = count_digits(n);
1284
- if (width > num_digits) out_ = std::fill_n(out_, width - num_digits, '0');
1285
- out_ = format_decimal<Char>(out_, n, num_digits).end;
1286
- }
1287
- void write_year(long long year) {
1288
- if (year >= 0 && year < 10000) {
1289
- write2(static_cast<int>(year / 100));
1290
- write2(static_cast<int>(year % 100));
1291
- } else {
1292
- write_year_extended(year);
1293
- }
1294
- }
1295
-
1296
- void write_utc_offset(long offset, numeric_system ns) {
1297
- if (offset < 0) {
1298
- *out_++ = '-';
1299
- offset = -offset;
1300
- } else {
1301
- *out_++ = '+';
1302
- }
1303
- offset /= 60;
1304
- write2(static_cast<int>(offset / 60));
1305
- if (ns != numeric_system::standard) *out_++ = ':';
1306
- write2(static_cast<int>(offset % 60));
1307
- }
1308
- template <typename T, FMT_ENABLE_IF(has_member_data_tm_gmtoff<T>::value)>
1309
- void format_utc_offset_impl(const T& tm, numeric_system ns) {
1310
- write_utc_offset(tm.tm_gmtoff, ns);
1311
- }
1312
- template <typename T, FMT_ENABLE_IF(!has_member_data_tm_gmtoff<T>::value)>
1313
- void format_utc_offset_impl(const T& tm, numeric_system ns) {
1314
- #if defined(_WIN32) && defined(_UCRT)
1315
- # if FMT_USE_TZSET
1316
- tzset_once();
1317
- # endif
1318
- long offset = 0;
1319
- _get_timezone(&offset);
1320
- if (tm.tm_isdst) {
1321
- long dstbias = 0;
1322
- _get_dstbias(&dstbias);
1323
- offset += dstbias;
1324
- }
1325
- write_utc_offset(-offset, ns);
1326
- #else
1327
- if (ns == numeric_system::standard) return format_localized('z');
1328
-
1329
- // Extract timezone offset from timezone conversion functions.
1330
- std::tm gtm = tm;
1331
- std::time_t gt = std::mktime(&gtm);
1332
- std::tm ltm = gmtime(gt);
1333
- std::time_t lt = std::mktime(&ltm);
1334
- long offset = gt - lt;
1335
- write_utc_offset(offset, ns);
1336
- #endif
1337
- }
1338
-
1339
- template <typename T, FMT_ENABLE_IF(has_member_data_tm_zone<T>::value)>
1340
- void format_tz_name_impl(const T& tm) {
1341
- if (is_classic_)
1342
- out_ = write_tm_str<Char>(out_, tm.tm_zone, loc_);
1343
- else
1344
- format_localized('Z');
1345
- }
1346
- template <typename T, FMT_ENABLE_IF(!has_member_data_tm_zone<T>::value)>
1347
- void format_tz_name_impl(const T&) {
1348
- format_localized('Z');
1349
- }
1350
-
1351
- void format_localized(char format, char modifier = 0) {
1352
- out_ = write<Char>(out_, tm_, loc_, format, modifier);
1353
- }
1354
-
1355
- public:
1356
- tm_writer(const std::locale& loc, OutputIt out, const std::tm& tm,
1357
- const Duration* subsecs = nullptr)
1358
- : loc_(loc),
1359
- is_classic_(loc_ == get_classic_locale()),
1360
- out_(out),
1361
- subsecs_(subsecs),
1362
- tm_(tm) {}
1363
-
1364
- auto out() const -> OutputIt { return out_; }
1365
-
1366
- FMT_CONSTEXPR void on_text(const Char* begin, const Char* end) {
1367
- out_ = copy_str<Char>(begin, end, out_);
1368
- }
1369
-
1370
- void on_abbr_weekday() {
1371
- if (is_classic_)
1372
- out_ = write(out_, tm_wday_short_name(tm_wday()));
1373
- else
1374
- format_localized('a');
1375
- }
1376
- void on_full_weekday() {
1377
- if (is_classic_)
1378
- out_ = write(out_, tm_wday_full_name(tm_wday()));
1379
- else
1380
- format_localized('A');
1381
- }
1382
- void on_dec0_weekday(numeric_system ns) {
1383
- if (is_classic_ || ns == numeric_system::standard) return write1(tm_wday());
1384
- format_localized('w', 'O');
1385
- }
1386
- void on_dec1_weekday(numeric_system ns) {
1387
- if (is_classic_ || ns == numeric_system::standard) {
1388
- auto wday = tm_wday();
1389
- write1(wday == 0 ? days_per_week : wday);
1390
- } else {
1391
- format_localized('u', 'O');
1392
- }
1393
- }
1394
-
1395
- void on_abbr_month() {
1396
- if (is_classic_)
1397
- out_ = write(out_, tm_mon_short_name(tm_mon()));
1398
- else
1399
- format_localized('b');
1400
- }
1401
- void on_full_month() {
1402
- if (is_classic_)
1403
- out_ = write(out_, tm_mon_full_name(tm_mon()));
1404
- else
1405
- format_localized('B');
1406
- }
1407
-
1408
- void on_datetime(numeric_system ns) {
1409
- if (is_classic_) {
1410
- on_abbr_weekday();
1411
- *out_++ = ' ';
1412
- on_abbr_month();
1413
- *out_++ = ' ';
1414
- on_day_of_month_space(numeric_system::standard);
1415
- *out_++ = ' ';
1416
- on_iso_time();
1417
- *out_++ = ' ';
1418
- on_year(numeric_system::standard);
1419
- } else {
1420
- format_localized('c', ns == numeric_system::standard ? '\0' : 'E');
1421
- }
1422
- }
1423
- void on_loc_date(numeric_system ns) {
1424
- if (is_classic_)
1425
- on_us_date();
1426
- else
1427
- format_localized('x', ns == numeric_system::standard ? '\0' : 'E');
1428
- }
1429
- void on_loc_time(numeric_system ns) {
1430
- if (is_classic_)
1431
- on_iso_time();
1432
- else
1433
- format_localized('X', ns == numeric_system::standard ? '\0' : 'E');
1434
- }
1435
- void on_us_date() {
1436
- char buf[8];
1437
- write_digit2_separated(buf, to_unsigned(tm_mon() + 1),
1438
- to_unsigned(tm_mday()),
1439
- to_unsigned(split_year_lower(tm_year())), '/');
1440
- out_ = copy_str<Char>(std::begin(buf), std::end(buf), out_);
1441
- }
1442
- void on_iso_date() {
1443
- auto year = tm_year();
1444
- char buf[10];
1445
- size_t offset = 0;
1446
- if (year >= 0 && year < 10000) {
1447
- copy2(buf, digits2(static_cast<size_t>(year / 100)));
1448
- } else {
1449
- offset = 4;
1450
- write_year_extended(year);
1451
- year = 0;
1452
- }
1453
- write_digit2_separated(buf + 2, static_cast<unsigned>(year % 100),
1454
- to_unsigned(tm_mon() + 1), to_unsigned(tm_mday()),
1455
- '-');
1456
- out_ = copy_str<Char>(std::begin(buf) + offset, std::end(buf), out_);
1457
- }
1458
-
1459
- void on_utc_offset(numeric_system ns) { format_utc_offset_impl(tm_, ns); }
1460
- void on_tz_name() { format_tz_name_impl(tm_); }
1461
-
1462
- void on_year(numeric_system ns) {
1463
- if (is_classic_ || ns == numeric_system::standard)
1464
- return write_year(tm_year());
1465
- format_localized('Y', 'E');
1466
- }
1467
- void on_short_year(numeric_system ns) {
1468
- if (is_classic_ || ns == numeric_system::standard)
1469
- return write2(split_year_lower(tm_year()));
1470
- format_localized('y', 'O');
1471
- }
1472
- void on_offset_year() {
1473
- if (is_classic_) return write2(split_year_lower(tm_year()));
1474
- format_localized('y', 'E');
1475
- }
1476
-
1477
- void on_century(numeric_system ns) {
1478
- if (is_classic_ || ns == numeric_system::standard) {
1479
- auto year = tm_year();
1480
- auto upper = year / 100;
1481
- if (year >= -99 && year < 0) {
1482
- // Zero upper on negative year.
1483
- *out_++ = '-';
1484
- *out_++ = '0';
1485
- } else if (upper >= 0 && upper < 100) {
1486
- write2(static_cast<int>(upper));
1487
- } else {
1488
- out_ = write<Char>(out_, upper);
1489
- }
1490
- } else {
1491
- format_localized('C', 'E');
1492
- }
1493
- }
1494
-
1495
- void on_dec_month(numeric_system ns) {
1496
- if (is_classic_ || ns == numeric_system::standard)
1497
- return write2(tm_mon() + 1);
1498
- format_localized('m', 'O');
1499
- }
1500
-
1501
- void on_dec0_week_of_year(numeric_system ns) {
1502
- if (is_classic_ || ns == numeric_system::standard)
1503
- return write2((tm_yday() + days_per_week - tm_wday()) / days_per_week);
1504
- format_localized('U', 'O');
1505
- }
1506
- void on_dec1_week_of_year(numeric_system ns) {
1507
- if (is_classic_ || ns == numeric_system::standard) {
1508
- auto wday = tm_wday();
1509
- write2((tm_yday() + days_per_week -
1510
- (wday == 0 ? (days_per_week - 1) : (wday - 1))) /
1511
- days_per_week);
1512
- } else {
1513
- format_localized('W', 'O');
1514
- }
1515
- }
1516
- void on_iso_week_of_year(numeric_system ns) {
1517
- if (is_classic_ || ns == numeric_system::standard)
1518
- return write2(tm_iso_week_of_year());
1519
- format_localized('V', 'O');
1520
- }
1521
-
1522
- void on_iso_week_based_year() { write_year(tm_iso_week_year()); }
1523
- void on_iso_week_based_short_year() {
1524
- write2(split_year_lower(tm_iso_week_year()));
1525
- }
1526
-
1527
- void on_day_of_year() {
1528
- auto yday = tm_yday() + 1;
1529
- write1(yday / 100);
1530
- write2(yday % 100);
1531
- }
1532
- void on_day_of_month(numeric_system ns) {
1533
- if (is_classic_ || ns == numeric_system::standard) return write2(tm_mday());
1534
- format_localized('d', 'O');
1535
- }
1536
- void on_day_of_month_space(numeric_system ns) {
1537
- if (is_classic_ || ns == numeric_system::standard) {
1538
- auto mday = to_unsigned(tm_mday()) % 100;
1539
- const char* d2 = digits2(mday);
1540
- *out_++ = mday < 10 ? ' ' : d2[0];
1541
- *out_++ = d2[1];
1542
- } else {
1543
- format_localized('e', 'O');
1544
- }
1545
- }
1546
-
1547
- void on_24_hour(numeric_system ns, pad_type pad) {
1548
- if (is_classic_ || ns == numeric_system::standard)
1549
- return write2(tm_hour(), pad);
1550
- format_localized('H', 'O');
1551
- }
1552
- void on_12_hour(numeric_system ns, pad_type pad) {
1553
- if (is_classic_ || ns == numeric_system::standard)
1554
- return write2(tm_hour12(), pad);
1555
- format_localized('I', 'O');
1556
- }
1557
- void on_minute(numeric_system ns, pad_type pad) {
1558
- if (is_classic_ || ns == numeric_system::standard)
1559
- return write2(tm_min(), pad);
1560
- format_localized('M', 'O');
1561
- }
1562
-
1563
- void on_second(numeric_system ns, pad_type pad) {
1564
- if (is_classic_ || ns == numeric_system::standard) {
1565
- write2(tm_sec(), pad);
1566
- if (subsecs_) {
1567
- if (std::is_floating_point<typename Duration::rep>::value) {
1568
- auto buf = memory_buffer();
1569
- write_floating_seconds(buf, *subsecs_);
1570
- if (buf.size() > 1) {
1571
- // Remove the leading "0", write something like ".123".
1572
- out_ = std::copy(buf.begin() + 1, buf.end(), out_);
1573
- }
1574
- } else {
1575
- write_fractional_seconds<Char>(out_, *subsecs_);
1576
- }
1577
- }
1578
- } else {
1579
- // Currently no formatting of subseconds when a locale is set.
1580
- format_localized('S', 'O');
1581
- }
1582
- }
1583
-
1584
- void on_12_hour_time() {
1585
- if (is_classic_) {
1586
- char buf[8];
1587
- write_digit2_separated(buf, to_unsigned(tm_hour12()),
1588
- to_unsigned(tm_min()), to_unsigned(tm_sec()), ':');
1589
- out_ = copy_str<Char>(std::begin(buf), std::end(buf), out_);
1590
- *out_++ = ' ';
1591
- on_am_pm();
1592
- } else {
1593
- format_localized('r');
1594
- }
1595
- }
1596
- void on_24_hour_time() {
1597
- write2(tm_hour());
1598
- *out_++ = ':';
1599
- write2(tm_min());
1600
- }
1601
- void on_iso_time() {
1602
- on_24_hour_time();
1603
- *out_++ = ':';
1604
- on_second(numeric_system::standard, pad_type::unspecified);
1605
- }
1606
-
1607
- void on_am_pm() {
1608
- if (is_classic_) {
1609
- *out_++ = tm_hour() < 12 ? 'A' : 'P';
1610
- *out_++ = 'M';
1611
- } else {
1612
- format_localized('p');
1613
- }
1614
- }
1615
-
1616
- // These apply to chrono durations but not tm.
1617
- void on_duration_value() {}
1618
- void on_duration_unit() {}
1619
- };
1620
-
1621
- struct chrono_format_checker : null_chrono_spec_handler<chrono_format_checker> {
1622
- bool has_precision_integral = false;
1623
-
1624
- FMT_NORETURN void unsupported() { FMT_THROW(format_error("no date")); }
1625
-
1626
- template <typename Char>
1627
- FMT_CONSTEXPR void on_text(const Char*, const Char*) {}
1628
- FMT_CONSTEXPR void on_day_of_year() {}
1629
- FMT_CONSTEXPR void on_24_hour(numeric_system, pad_type) {}
1630
- FMT_CONSTEXPR void on_12_hour(numeric_system, pad_type) {}
1631
- FMT_CONSTEXPR void on_minute(numeric_system, pad_type) {}
1632
- FMT_CONSTEXPR void on_second(numeric_system, pad_type) {}
1633
- FMT_CONSTEXPR void on_12_hour_time() {}
1634
- FMT_CONSTEXPR void on_24_hour_time() {}
1635
- FMT_CONSTEXPR void on_iso_time() {}
1636
- FMT_CONSTEXPR void on_am_pm() {}
1637
- FMT_CONSTEXPR void on_duration_value() const {
1638
- if (has_precision_integral) {
1639
- FMT_THROW(format_error("precision not allowed for this argument type"));
1640
- }
1641
- }
1642
- FMT_CONSTEXPR void on_duration_unit() {}
1643
- };
1644
-
1645
- template <typename T,
1646
- FMT_ENABLE_IF(std::is_integral<T>::value&& has_isfinite<T>::value)>
1647
- inline auto isfinite(T) -> bool {
1648
- return true;
1649
- }
1650
-
1651
- template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
1652
- inline auto mod(T x, int y) -> T {
1653
- return x % static_cast<T>(y);
1654
- }
1655
- template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
1656
- inline auto mod(T x, int y) -> T {
1657
- return std::fmod(x, static_cast<T>(y));
1658
- }
1659
-
1660
- // If T is an integral type, maps T to its unsigned counterpart, otherwise
1661
- // leaves it unchanged (unlike std::make_unsigned).
1662
- template <typename T, bool INTEGRAL = std::is_integral<T>::value>
1663
- struct make_unsigned_or_unchanged {
1664
- using type = T;
1665
- };
1666
-
1667
- template <typename T> struct make_unsigned_or_unchanged<T, true> {
1668
- using type = typename std::make_unsigned<T>::type;
1669
- };
1670
-
1671
- template <typename Rep, typename Period,
1672
- FMT_ENABLE_IF(std::is_integral<Rep>::value)>
1673
- inline auto get_milliseconds(std::chrono::duration<Rep, Period> d)
1674
- -> std::chrono::duration<Rep, std::milli> {
1675
- // this may overflow and/or the result may not fit in the
1676
- // target type.
1677
- #if FMT_SAFE_DURATION_CAST
1678
- using CommonSecondsType =
1679
- typename std::common_type<decltype(d), std::chrono::seconds>::type;
1680
- const auto d_as_common = fmt_duration_cast<CommonSecondsType>(d);
1681
- const auto d_as_whole_seconds =
1682
- fmt_duration_cast<std::chrono::seconds>(d_as_common);
1683
- // this conversion should be nonproblematic
1684
- const auto diff = d_as_common - d_as_whole_seconds;
1685
- const auto ms =
1686
- fmt_duration_cast<std::chrono::duration<Rep, std::milli>>(diff);
1687
- return ms;
1688
- #else
1689
- auto s = fmt_duration_cast<std::chrono::seconds>(d);
1690
- return fmt_duration_cast<std::chrono::milliseconds>(d - s);
1691
- #endif
1692
- }
1693
-
1694
- template <typename Char, typename Rep, typename OutputIt,
1695
- FMT_ENABLE_IF(std::is_integral<Rep>::value)>
1696
- auto format_duration_value(OutputIt out, Rep val, int) -> OutputIt {
1697
- return write<Char>(out, val);
1698
- }
1699
-
1700
- template <typename Char, typename Rep, typename OutputIt,
1701
- FMT_ENABLE_IF(std::is_floating_point<Rep>::value)>
1702
- auto format_duration_value(OutputIt out, Rep val, int precision) -> OutputIt {
1703
- auto specs = format_specs<Char>();
1704
- specs.precision = precision;
1705
- specs.type = precision >= 0 ? presentation_type::fixed_lower
1706
- : presentation_type::general_lower;
1707
- return write<Char>(out, val, specs);
1708
- }
1709
-
1710
- template <typename Char, typename OutputIt>
1711
- auto copy_unit(string_view unit, OutputIt out, Char) -> OutputIt {
1712
- return std::copy(unit.begin(), unit.end(), out);
1713
- }
1714
-
1715
- template <typename OutputIt>
1716
- auto copy_unit(string_view unit, OutputIt out, wchar_t) -> OutputIt {
1717
- // This works when wchar_t is UTF-32 because units only contain characters
1718
- // that have the same representation in UTF-16 and UTF-32.
1719
- utf8_to_utf16 u(unit);
1720
- return std::copy(u.c_str(), u.c_str() + u.size(), out);
1721
- }
1722
-
1723
- template <typename Char, typename Period, typename OutputIt>
1724
- auto format_duration_unit(OutputIt out) -> OutputIt {
1725
- if (const char* unit = get_units<Period>())
1726
- return copy_unit(string_view(unit), out, Char());
1727
- *out++ = '[';
1728
- out = write<Char>(out, Period::num);
1729
- if (const_check(Period::den != 1)) {
1730
- *out++ = '/';
1731
- out = write<Char>(out, Period::den);
1732
- }
1733
- *out++ = ']';
1734
- *out++ = 's';
1735
- return out;
1736
- }
1737
-
1738
- class get_locale {
1739
- private:
1740
- union {
1741
- std::locale locale_;
1742
- };
1743
- bool has_locale_ = false;
1744
-
1745
- public:
1746
- get_locale(bool localized, locale_ref loc) : has_locale_(localized) {
1747
- if (localized)
1748
- ::new (&locale_) std::locale(loc.template get<std::locale>());
1749
- }
1750
- ~get_locale() {
1751
- if (has_locale_) locale_.~locale();
1752
- }
1753
- operator const std::locale&() const {
1754
- return has_locale_ ? locale_ : get_classic_locale();
1755
- }
1756
- };
1757
-
1758
- template <typename FormatContext, typename OutputIt, typename Rep,
1759
- typename Period>
1760
- struct chrono_formatter {
1761
- FormatContext& context;
1762
- OutputIt out;
1763
- int precision;
1764
- bool localized = false;
1765
- // rep is unsigned to avoid overflow.
1766
- using rep =
1767
- conditional_t<std::is_integral<Rep>::value && sizeof(Rep) < sizeof(int),
1768
- unsigned, typename make_unsigned_or_unchanged<Rep>::type>;
1769
- rep val;
1770
- using seconds = std::chrono::duration<rep>;
1771
- seconds s;
1772
- using milliseconds = std::chrono::duration<rep, std::milli>;
1773
- bool negative;
1774
-
1775
- using char_type = typename FormatContext::char_type;
1776
- using tm_writer_type = tm_writer<OutputIt, char_type>;
1777
-
1778
- chrono_formatter(FormatContext& ctx, OutputIt o,
1779
- std::chrono::duration<Rep, Period> d)
1780
- : context(ctx),
1781
- out(o),
1782
- val(static_cast<rep>(d.count())),
1783
- negative(false) {
1784
- if (d.count() < 0) {
1785
- val = 0 - val;
1786
- negative = true;
1787
- }
1788
-
1789
- // this may overflow and/or the result may not fit in the
1790
- // target type.
1791
- // might need checked conversion (rep!=Rep)
1792
- s = fmt_duration_cast<seconds>(std::chrono::duration<rep, Period>(val));
1793
- }
1794
-
1795
- // returns true if nan or inf, writes to out.
1796
- auto handle_nan_inf() -> bool {
1797
- if (isfinite(val)) {
1798
- return false;
1799
- }
1800
- if (isnan(val)) {
1801
- write_nan();
1802
- return true;
1803
- }
1804
- // must be +-inf
1805
- if (val > 0) {
1806
- write_pinf();
1807
- } else {
1808
- write_ninf();
1809
- }
1810
- return true;
1811
- }
1812
-
1813
- auto days() const -> Rep { return static_cast<Rep>(s.count() / 86400); }
1814
- auto hour() const -> Rep {
1815
- return static_cast<Rep>(mod((s.count() / 3600), 24));
1816
- }
1817
-
1818
- auto hour12() const -> Rep {
1819
- Rep hour = static_cast<Rep>(mod((s.count() / 3600), 12));
1820
- return hour <= 0 ? 12 : hour;
1821
- }
1822
-
1823
- auto minute() const -> Rep {
1824
- return static_cast<Rep>(mod((s.count() / 60), 60));
1825
- }
1826
- auto second() const -> Rep { return static_cast<Rep>(mod(s.count(), 60)); }
1827
-
1828
- auto time() const -> std::tm {
1829
- auto time = std::tm();
1830
- time.tm_hour = to_nonnegative_int(hour(), 24);
1831
- time.tm_min = to_nonnegative_int(minute(), 60);
1832
- time.tm_sec = to_nonnegative_int(second(), 60);
1833
- return time;
1834
- }
1835
-
1836
- void write_sign() {
1837
- if (negative) {
1838
- *out++ = '-';
1839
- negative = false;
1840
- }
1841
- }
1842
-
1843
- void write(Rep value, int width, pad_type pad = pad_type::unspecified) {
1844
- write_sign();
1845
- if (isnan(value)) return write_nan();
1846
- uint32_or_64_or_128_t<int> n =
1847
- to_unsigned(to_nonnegative_int(value, max_value<int>()));
1848
- int num_digits = detail::count_digits(n);
1849
- if (width > num_digits) {
1850
- out = detail::write_padding(out, pad, width - num_digits);
1851
- }
1852
- out = format_decimal<char_type>(out, n, num_digits).end;
1853
- }
1854
-
1855
- void write_nan() { std::copy_n("nan", 3, out); }
1856
- void write_pinf() { std::copy_n("inf", 3, out); }
1857
- void write_ninf() { std::copy_n("-inf", 4, out); }
1858
-
1859
- template <typename Callback, typename... Args>
1860
- void format_tm(const tm& time, Callback cb, Args... args) {
1861
- if (isnan(val)) return write_nan();
1862
- get_locale loc(localized, context.locale());
1863
- auto w = tm_writer_type(loc, out, time);
1864
- (w.*cb)(args...);
1865
- out = w.out();
1866
- }
1867
-
1868
- void on_text(const char_type* begin, const char_type* end) {
1869
- std::copy(begin, end, out);
1870
- }
1871
-
1872
- // These are not implemented because durations don't have date information.
1873
- void on_abbr_weekday() {}
1874
- void on_full_weekday() {}
1875
- void on_dec0_weekday(numeric_system) {}
1876
- void on_dec1_weekday(numeric_system) {}
1877
- void on_abbr_month() {}
1878
- void on_full_month() {}
1879
- void on_datetime(numeric_system) {}
1880
- void on_loc_date(numeric_system) {}
1881
- void on_loc_time(numeric_system) {}
1882
- void on_us_date() {}
1883
- void on_iso_date() {}
1884
- void on_utc_offset(numeric_system) {}
1885
- void on_tz_name() {}
1886
- void on_year(numeric_system) {}
1887
- void on_short_year(numeric_system) {}
1888
- void on_offset_year() {}
1889
- void on_century(numeric_system) {}
1890
- void on_iso_week_based_year() {}
1891
- void on_iso_week_based_short_year() {}
1892
- void on_dec_month(numeric_system) {}
1893
- void on_dec0_week_of_year(numeric_system) {}
1894
- void on_dec1_week_of_year(numeric_system) {}
1895
- void on_iso_week_of_year(numeric_system) {}
1896
- void on_day_of_month(numeric_system) {}
1897
- void on_day_of_month_space(numeric_system) {}
1898
-
1899
- void on_day_of_year() {
1900
- if (handle_nan_inf()) return;
1901
- write(days(), 0);
1902
- }
1903
-
1904
- void on_24_hour(numeric_system ns, pad_type pad) {
1905
- if (handle_nan_inf()) return;
1906
-
1907
- if (ns == numeric_system::standard) return write(hour(), 2, pad);
1908
- auto time = tm();
1909
- time.tm_hour = to_nonnegative_int(hour(), 24);
1910
- format_tm(time, &tm_writer_type::on_24_hour, ns, pad);
1911
- }
1912
-
1913
- void on_12_hour(numeric_system ns, pad_type pad) {
1914
- if (handle_nan_inf()) return;
1915
-
1916
- if (ns == numeric_system::standard) return write(hour12(), 2, pad);
1917
- auto time = tm();
1918
- time.tm_hour = to_nonnegative_int(hour12(), 12);
1919
- format_tm(time, &tm_writer_type::on_12_hour, ns, pad);
1920
- }
1921
-
1922
- void on_minute(numeric_system ns, pad_type pad) {
1923
- if (handle_nan_inf()) return;
1924
-
1925
- if (ns == numeric_system::standard) return write(minute(), 2, pad);
1926
- auto time = tm();
1927
- time.tm_min = to_nonnegative_int(minute(), 60);
1928
- format_tm(time, &tm_writer_type::on_minute, ns, pad);
1929
- }
1930
-
1931
- void on_second(numeric_system ns, pad_type pad) {
1932
- if (handle_nan_inf()) return;
1933
-
1934
- if (ns == numeric_system::standard) {
1935
- if (std::is_floating_point<rep>::value) {
1936
- auto buf = memory_buffer();
1937
- write_floating_seconds(buf, std::chrono::duration<rep, Period>(val),
1938
- precision);
1939
- if (negative) *out++ = '-';
1940
- if (buf.size() < 2 || buf[1] == '.') {
1941
- out = detail::write_padding(out, pad);
1942
- }
1943
- out = std::copy(buf.begin(), buf.end(), out);
1944
- } else {
1945
- write(second(), 2, pad);
1946
- write_fractional_seconds<char_type>(
1947
- out, std::chrono::duration<rep, Period>(val), precision);
1948
- }
1949
- return;
1950
- }
1951
- auto time = tm();
1952
- time.tm_sec = to_nonnegative_int(second(), 60);
1953
- format_tm(time, &tm_writer_type::on_second, ns, pad);
1954
- }
1955
-
1956
- void on_12_hour_time() {
1957
- if (handle_nan_inf()) return;
1958
- format_tm(time(), &tm_writer_type::on_12_hour_time);
1959
- }
1960
-
1961
- void on_24_hour_time() {
1962
- if (handle_nan_inf()) {
1963
- *out++ = ':';
1964
- handle_nan_inf();
1965
- return;
1966
- }
1967
-
1968
- write(hour(), 2);
1969
- *out++ = ':';
1970
- write(minute(), 2);
1971
- }
1972
-
1973
- void on_iso_time() {
1974
- on_24_hour_time();
1975
- *out++ = ':';
1976
- if (handle_nan_inf()) return;
1977
- on_second(numeric_system::standard, pad_type::unspecified);
1978
- }
1979
-
1980
- void on_am_pm() {
1981
- if (handle_nan_inf()) return;
1982
- format_tm(time(), &tm_writer_type::on_am_pm);
1983
- }
1984
-
1985
- void on_duration_value() {
1986
- if (handle_nan_inf()) return;
1987
- write_sign();
1988
- out = format_duration_value<char_type>(out, val, precision);
1989
- }
1990
-
1991
- void on_duration_unit() {
1992
- out = format_duration_unit<char_type, Period>(out);
1993
- }
1994
- };
1995
-
1996
- } // namespace detail
1997
-
1998
- #if defined(__cpp_lib_chrono) && __cpp_lib_chrono >= 201907
1999
- using weekday = std::chrono::weekday;
2000
- #else
2001
- // A fallback version of weekday.
2002
- class weekday {
2003
- private:
2004
- unsigned char value;
2005
-
2006
- public:
2007
- weekday() = default;
2008
- explicit constexpr weekday(unsigned wd) noexcept
2009
- : value(static_cast<unsigned char>(wd != 7 ? wd : 0)) {}
2010
- constexpr auto c_encoding() const noexcept -> unsigned { return value; }
2011
- };
2012
-
2013
- class year_month_day {};
2014
- #endif
2015
-
2016
- // A rudimentary weekday formatter.
2017
- template <typename Char> struct formatter<weekday, Char> {
2018
- private:
2019
- bool localized = false;
2020
-
2021
- public:
2022
- FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
2023
- -> decltype(ctx.begin()) {
2024
- auto begin = ctx.begin(), end = ctx.end();
2025
- if (begin != end && *begin == 'L') {
2026
- ++begin;
2027
- localized = true;
2028
- }
2029
- return begin;
2030
- }
2031
-
2032
- template <typename FormatContext>
2033
- auto format(weekday wd, FormatContext& ctx) const -> decltype(ctx.out()) {
2034
- auto time = std::tm();
2035
- time.tm_wday = static_cast<int>(wd.c_encoding());
2036
- detail::get_locale loc(localized, ctx.locale());
2037
- auto w = detail::tm_writer<decltype(ctx.out()), Char>(loc, ctx.out(), time);
2038
- w.on_abbr_weekday();
2039
- return w.out();
2040
- }
2041
- };
2042
-
2043
- template <typename Rep, typename Period, typename Char>
2044
- struct formatter<std::chrono::duration<Rep, Period>, Char> {
2045
- private:
2046
- format_specs<Char> specs_;
2047
- detail::arg_ref<Char> width_ref_;
2048
- detail::arg_ref<Char> precision_ref_;
2049
- bool localized_ = false;
2050
- basic_string_view<Char> format_str_;
2051
-
2052
- public:
2053
- FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
2054
- -> decltype(ctx.begin()) {
2055
- auto it = ctx.begin(), end = ctx.end();
2056
- if (it == end || *it == '}') return it;
2057
-
2058
- it = detail::parse_align(it, end, specs_);
2059
- if (it == end) return it;
2060
-
2061
- it = detail::parse_dynamic_spec(it, end, specs_.width, width_ref_, ctx);
2062
- if (it == end) return it;
2063
-
2064
- auto checker = detail::chrono_format_checker();
2065
- if (*it == '.') {
2066
- checker.has_precision_integral = !std::is_floating_point<Rep>::value;
2067
- it = detail::parse_precision(it, end, specs_.precision, precision_ref_,
2068
- ctx);
2069
- }
2070
- if (it != end && *it == 'L') {
2071
- localized_ = true;
2072
- ++it;
2073
- }
2074
- end = detail::parse_chrono_format(it, end, checker);
2075
- format_str_ = {it, detail::to_unsigned(end - it)};
2076
- return end;
2077
- }
2078
-
2079
- template <typename FormatContext>
2080
- auto format(std::chrono::duration<Rep, Period> d, FormatContext& ctx) const
2081
- -> decltype(ctx.out()) {
2082
- auto specs = specs_;
2083
- auto precision = specs.precision;
2084
- specs.precision = -1;
2085
- auto begin = format_str_.begin(), end = format_str_.end();
2086
- // As a possible future optimization, we could avoid extra copying if width
2087
- // is not specified.
2088
- auto buf = basic_memory_buffer<Char>();
2089
- auto out = std::back_inserter(buf);
2090
- detail::handle_dynamic_spec<detail::width_checker>(specs.width, width_ref_,
2091
- ctx);
2092
- detail::handle_dynamic_spec<detail::precision_checker>(precision,
2093
- precision_ref_, ctx);
2094
- if (begin == end || *begin == '}') {
2095
- out = detail::format_duration_value<Char>(out, d.count(), precision);
2096
- detail::format_duration_unit<Char, Period>(out);
2097
- } else {
2098
- using chrono_formatter =
2099
- detail::chrono_formatter<FormatContext, decltype(out), Rep, Period>;
2100
- auto f = chrono_formatter(ctx, out, d);
2101
- f.precision = precision;
2102
- f.localized = localized_;
2103
- detail::parse_chrono_format(begin, end, f);
2104
- }
2105
- return detail::write(
2106
- ctx.out(), basic_string_view<Char>(buf.data(), buf.size()), specs);
2107
- }
2108
- };
2109
-
2110
- template <typename Char, typename Duration>
2111
- struct formatter<std::chrono::time_point<std::chrono::system_clock, Duration>,
2112
- Char> : formatter<std::tm, Char> {
2113
- FMT_CONSTEXPR formatter() {
2114
- this->format_str_ = detail::string_literal<Char, '%', 'F', ' ', '%', 'T'>{};
2115
- }
2116
-
2117
- template <typename FormatContext>
2118
- auto format(std::chrono::time_point<std::chrono::system_clock, Duration> val,
2119
- FormatContext& ctx) const -> decltype(ctx.out()) {
2120
- using period = typename Duration::period;
2121
- if (detail::const_check(
2122
- period::num != 1 || period::den != 1 ||
2123
- std::is_floating_point<typename Duration::rep>::value)) {
2124
- const auto epoch = val.time_since_epoch();
2125
- auto subsecs = detail::fmt_duration_cast<Duration>(
2126
- epoch - detail::fmt_duration_cast<std::chrono::seconds>(epoch));
2127
-
2128
- if (subsecs.count() < 0) {
2129
- auto second =
2130
- detail::fmt_duration_cast<Duration>(std::chrono::seconds(1));
2131
- if (epoch.count() < ((Duration::min)() + second).count())
2132
- FMT_THROW(format_error("duration is too small"));
2133
- subsecs += second;
2134
- val -= second;
2135
- }
2136
-
2137
- return formatter<std::tm, Char>::do_format(gmtime(val), ctx, &subsecs);
2138
- }
2139
-
2140
- return formatter<std::tm, Char>::format(gmtime(val), ctx);
2141
- }
2142
- };
2143
-
2144
- #if FMT_USE_LOCAL_TIME
2145
- template <typename Char, typename Duration>
2146
- struct formatter<std::chrono::local_time<Duration>, Char>
2147
- : formatter<std::tm, Char> {
2148
- FMT_CONSTEXPR formatter() {
2149
- this->format_str_ = detail::string_literal<Char, '%', 'F', ' ', '%', 'T'>{};
2150
- }
2151
-
2152
- template <typename FormatContext>
2153
- auto format(std::chrono::local_time<Duration> val, FormatContext& ctx) const
2154
- -> decltype(ctx.out()) {
2155
- using period = typename Duration::period;
2156
- if (period::num != 1 || period::den != 1 ||
2157
- std::is_floating_point<typename Duration::rep>::value) {
2158
- const auto epoch = val.time_since_epoch();
2159
- const auto subsecs = detail::fmt_duration_cast<Duration>(
2160
- epoch - detail::fmt_duration_cast<std::chrono::seconds>(epoch));
2161
-
2162
- return formatter<std::tm, Char>::do_format(localtime(val), ctx, &subsecs);
2163
- }
2164
-
2165
- return formatter<std::tm, Char>::format(localtime(val), ctx);
2166
- }
2167
- };
2168
- #endif
2169
-
2170
- #if FMT_USE_UTC_TIME
2171
- template <typename Char, typename Duration>
2172
- struct formatter<std::chrono::time_point<std::chrono::utc_clock, Duration>,
2173
- Char>
2174
- : formatter<std::chrono::time_point<std::chrono::system_clock, Duration>,
2175
- Char> {
2176
- template <typename FormatContext>
2177
- auto format(std::chrono::time_point<std::chrono::utc_clock, Duration> val,
2178
- FormatContext& ctx) const -> decltype(ctx.out()) {
2179
- return formatter<
2180
- std::chrono::time_point<std::chrono::system_clock, Duration>,
2181
- Char>::format(std::chrono::utc_clock::to_sys(val), ctx);
2182
- }
2183
- };
2184
- #endif
2185
-
2186
- template <typename Char> struct formatter<std::tm, Char> {
2187
- private:
2188
- format_specs<Char> specs_;
2189
- detail::arg_ref<Char> width_ref_;
2190
-
2191
- protected:
2192
- basic_string_view<Char> format_str_;
2193
-
2194
- template <typename FormatContext, typename Duration>
2195
- auto do_format(const std::tm& tm, FormatContext& ctx,
2196
- const Duration* subsecs) const -> decltype(ctx.out()) {
2197
- auto specs = specs_;
2198
- auto buf = basic_memory_buffer<Char>();
2199
- auto out = std::back_inserter(buf);
2200
- detail::handle_dynamic_spec<detail::width_checker>(specs.width, width_ref_,
2201
- ctx);
2202
-
2203
- auto loc_ref = ctx.locale();
2204
- detail::get_locale loc(static_cast<bool>(loc_ref), loc_ref);
2205
- auto w =
2206
- detail::tm_writer<decltype(out), Char, Duration>(loc, out, tm, subsecs);
2207
- detail::parse_chrono_format(format_str_.begin(), format_str_.end(), w);
2208
- return detail::write(
2209
- ctx.out(), basic_string_view<Char>(buf.data(), buf.size()), specs);
2210
- }
2211
-
2212
- public:
2213
- FMT_CONSTEXPR auto parse(basic_format_parse_context<Char>& ctx)
2214
- -> decltype(ctx.begin()) {
2215
- auto it = ctx.begin(), end = ctx.end();
2216
- if (it == end || *it == '}') return it;
2217
-
2218
- it = detail::parse_align(it, end, specs_);
2219
- if (it == end) return it;
2220
-
2221
- it = detail::parse_dynamic_spec(it, end, specs_.width, width_ref_, ctx);
2222
- if (it == end) return it;
2223
-
2224
- end = detail::parse_chrono_format(it, end, detail::tm_format_checker());
2225
- // Replace the default format_str only if the new spec is not empty.
2226
- if (end != it) format_str_ = {it, detail::to_unsigned(end - it)};
2227
- return end;
2228
- }
2229
-
2230
- template <typename FormatContext>
2231
- auto format(const std::tm& tm, FormatContext& ctx) const
2232
- -> decltype(ctx.out()) {
2233
- return do_format<FormatContext, std::chrono::seconds>(tm, ctx, nullptr);
2234
- }
2235
- };
2236
-
2237
- FMT_END_EXPORT
2238
- FMT_END_NAMESPACE
2239
-
2240
- #endif // FMT_CHRONO_H_