iceberg-cpp
Loading...
Searching...
No Matches
formatter_internal.h
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20#pragma once
21
22#include <concepts>
23#include <format>
24#include <map>
25#include <ranges>
26#include <sstream>
27#include <string_view>
28#include <unordered_map>
29#include <unordered_set>
30#include <vector>
31
33
35template <typename T>
36concept SmartPointerType = requires(T t) {
37 { t.operator->() } -> std::same_as<typename T::element_type*>;
38 { *t } -> std::convertible_to<typename T::element_type&>;
39 { static_cast<bool>(t) } -> std::same_as<bool>;
40 typename T::element_type;
41};
42
44template <typename T>
45std::string FormatItem(const T& item) {
46 if constexpr (SmartPointerType<T>) {
47 if (item) {
48 return std::format("{}", *item);
49 } else {
50 return "null";
51 }
52 } else {
53 return std::format("{}", item);
54 }
55}
56
59template <std::ranges::input_range Range>
60std::string FormatRange(const Range& range, std::string_view separator,
61 std::string_view prefix, std::string_view suffix) {
62 if (std::ranges::empty(range)) {
63 return std::format("{}{}", prefix, suffix);
64 }
65
66 std::stringstream ss;
67 ss << prefix;
68
69 bool first = true;
70 for (const auto& element : range) {
71 if (!first) {
72 ss << separator;
73 }
74 ss << std::format("{}", element);
75 first = false;
76 }
77
78 ss << suffix;
79 return ss.str();
80}
81
83template <typename MapType>
84std::string FormatMap(const MapType& map) {
85 // Transform the map items into formatted key-value pairs
86 std::ranges::transform_view formatted_range =
87 map | std::views::transform([](const auto& pair) -> std::string {
88 const auto& [key, value] = pair;
89 return std::format("{}: {}", FormatItem(key), FormatItem(value));
90 });
91 return FormatRange(formatted_range, ", ", "{", "}");
92}
93
95template <typename K, typename V>
96struct std::formatter<std::map<K, V>> : std::formatter<std::string_view> {
97 template <class FormatContext>
98 auto format(const std::map<K, V>& map, FormatContext& ctx) const {
99 return std::formatter<std::string_view>::format(FormatMap(map), ctx);
100 }
101};
102
104template <typename K, typename V>
105struct std::formatter<std::unordered_map<K, V>> : std::formatter<std::string_view> {
106 template <class FormatContext>
107 auto format(const std::unordered_map<K, V>& map, FormatContext& ctx) const {
108 return std::formatter<std::string_view>::format(FormatMap(map), ctx);
109 }
110};
111
113template <typename T>
114struct std::formatter<std::vector<T>> : std::formatter<std::string_view> {
115 template <class FormatContext>
116 auto format(const std::vector<T>& vec, FormatContext& ctx) const {
117 auto formatted_range =
118 vec | std::views::transform([](const auto& item) { return FormatItem(item); });
119 return std::formatter<std::string_view>::format(
120 FormatRange(formatted_range, ", ", "[", "]"), ctx);
121 }
122};
123
125template <typename T, size_t Extent>
126struct std::formatter<std::span<T, Extent>> : std::formatter<std::string_view> {
127 template <class FormatContext>
128 auto format(const std::span<T, Extent>& span, FormatContext& ctx) const {
129 auto formatted_range =
130 span | std::views::transform([](const auto& item) { return FormatItem(item); });
131 return std::formatter<std::string_view>::format(
132 FormatRange(formatted_range, ", ", "[", "]"), ctx);
133 }
134};
135
137template <typename T, typename Hash, typename KeyEqual, typename Allocator>
138struct std::formatter<std::unordered_set<T, Hash, KeyEqual, Allocator>>
139 : std::formatter<std::string_view> {
140 template <class FormatContext>
141 auto format(const std::unordered_set<T, Hash, KeyEqual, Allocator>& set,
142 FormatContext& ctx) const {
143 auto formatted_range =
144 set | std::views::transform([](const auto& item) { return FormatItem(item); });
145 return std::formatter<std::string_view>::format(
146 FormatRange(formatted_range, ", ", "[", "]"), ctx);
147 }
148};
Concept for smart pointer types.
Definition formatter_internal.h:36
std::shared_ptr< MapType > map(SchemaField key, SchemaField value)
Create a MapType with the given key and value fields.
Definition type.cc:388
STL namespace.