Phosphor
trace_argument.h
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  * Copyright 2016 Couchbase, Inc
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
22 #pragma once
23 
24 #include <cstddef>
25 #include <sstream>
26 #include <stdexcept>
27 #include <string>
28 #include <type_traits>
29 
30 #include "inline_zstring.h"
31 #include "platform/core.h"
32 
33 namespace phosphor {
34 
38  struct NoneType {
39  };
40 
47  union TraceArgument {
51  enum class Type : char {
52  is_bool,
53  is_uint,
54  is_int,
55  is_double,
56  is_pointer,
57  is_string,
58  is_istring,
59  is_none
60  };
61 
62  bool as_bool;
63  unsigned long long as_uint;
64  long long as_int;
65  double as_double;
66  const char* as_string;
67  const void* as_pointer;
68  inline_zstring<8> as_istring;
69  NoneType as_none;
70 
74  TraceArgument() = default;
75 
88  template <class T>
89  inline constexpr TraceArgument(T src);
90 
97  inline std::string to_string(TraceArgument::Type type) const;
98 
99  private:
100  template <TraceArgument::Type T>
101  inline std::string internal_to_string();
102  };
103 
108  template <typename T>
110  public:
114  inline static constexpr TraceArgument::Type getType();
115 
120  inline static constexpr TraceArgument asArgument(T arg);
121  };
122 
123  static_assert(sizeof(TraceArgument) <= 8,
124  "TraceArgument must be 8 or less bytes");
125 
134 #define ARGUMENT_CONVERSION(src, dst) \
135  template <> \
136  inline constexpr TraceArgument::TraceArgument(src arg) : as_##dst(arg) {} \
137  template<> \
138  class TraceArgumentConversion<src> { \
139  public:\
140  inline static constexpr TraceArgument::Type getType() { \
141  return TraceArgument::Type::is_##dst; \
142  } \
143  \
144  inline static constexpr TraceArgument asArgument(src arg) { \
145  return TraceArgument(arg); \
146  } \
147  };
148 
149  ARGUMENT_CONVERSION(bool, bool)
150 
151  ARGUMENT_CONVERSION(char, int)
152 
153  ARGUMENT_CONVERSION(short, int)
154 
155  ARGUMENT_CONVERSION(int, int)
156 
157  ARGUMENT_CONVERSION(long, int)
158 
159  ARGUMENT_CONVERSION(long long, int)
160 
161  ARGUMENT_CONVERSION(unsigned char, uint)
162 
163  ARGUMENT_CONVERSION(unsigned short, uint)
164 
165  ARGUMENT_CONVERSION(unsigned int, uint)
166 
167  ARGUMENT_CONVERSION(unsigned long, uint)
168 
169  ARGUMENT_CONVERSION(unsigned long long, uint)
170 
171  ARGUMENT_CONVERSION(float, double)
172 
173  ARGUMENT_CONVERSION(double, double)
174 
175  ARGUMENT_CONVERSION(const void*, pointer)
176 
177  // A nullptr isn't particulary useful to store in the trace event;
178  // but aids in use with generic code where a pointer type ends up
179  // as nullptr.
180  ARGUMENT_CONVERSION(std::nullptr_t, pointer)
181 
182  ARGUMENT_CONVERSION(const char*, string)
183 
184  ARGUMENT_CONVERSION(inline_zstring<8>, istring)
185 
186  ARGUMENT_CONVERSION(NoneType, none)
187 
188 #undef ARGUMENT_CONVERSION
189 
193  template<typename T>
195  public:
196 
197  inline static constexpr TraceArgument::Type getType() {
198  return TraceArgument::Type::is_pointer;
199  }
200 
201  inline static constexpr TraceArgument asArgument(T* arg) {
202 
203  // This relies on the 'const void*' -> pointer
204  // conversion defined above.
205  return TraceArgument(static_cast<const void*>(arg));
206  }
207  };
208 
209  inline std::string TraceArgument::to_string(
210  TraceArgument::Type type) const {
211  std::stringstream ss;
212  switch (type) {
213  case Type::is_bool:
214  return as_bool ? "true" : "false";
215  case Type::is_int:
216  return std::to_string(as_int);
217  case Type::is_uint:
218  return std::to_string(as_uint);
219  case Type::is_double:
220  return std::to_string(as_double);
221  case Type::is_pointer:
222  ss << as_pointer;
223  return "\"" + ss.str() + "\"";
224  case Type::is_string:
225  return "\"" + std::string(as_string) + "\"";
226  case Type::is_istring:
227  return "\"" + std::string(as_istring) + "\"";
228  case Type::is_none:
229  return std::string("\"Type::is_none\"");
230  }
231  throw std::invalid_argument("Invalid TraceArgument type");
232  }
233 } // namespace phosphor
Type
Definition: trace_argument.h:51
Definition: trace_argument.h:109
Definition: trace_argument.h:47
std::string to_string(TraceArgument::Type type) const
Definition: trace_argument.h:209
Definition: trace_argument.h:38
#define ARGUMENT_CONVERSION(src, dst)
Definition: trace_argument.h:134
Definition: category_registry.h:32