1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <cstdlib>
19 #include <string_view>
20 
21 namespace cuttlefish {
22 
23 namespace internal {
24 
25 template <typename T>
26 struct CompileTimeTypeName {
PrettyFnCompileTimeTypeName27   static constexpr std::string_view PrettyFn() { return __PRETTY_FUNCTION__; }
28 };
29 
30 template <auto T>
31 struct CompileTimeValueName {
PrettyFnCompileTimeValueName32   static constexpr std::string_view PrettyFn() { return __PRETTY_FUNCTION__; }
33 };
34 
ExtractName(std::string_view name)35 constexpr std::string_view ExtractName(std::string_view name) {
36   std::string_view value_prefix = "internal::CompileTimeValueName<";
37   if (auto begin = name.find(value_prefix); begin != std::string_view::npos) {
38     name = name.substr(begin + value_prefix.size());
39   }
40 
41   std::string_view type_prefix = "internal::CompileTimeTypeName<";
42   if (auto begin = name.find(type_prefix); begin != std::string_view::npos) {
43     name = name.substr(begin + type_prefix.size());
44   }
45 
46   if (name.size() > 0 && name[0] == '&') {
47     name = name.substr(1);
48   }
49 
50   constexpr std::string_view suffix = ">::PrettyFn";
51   if (auto begin = name.rfind(suffix); begin != std::string_view::npos) {
52     name = name.substr(0, begin);
53   }
54 
55   return name;
56 }
57 
58 }  // namespace internal
59 
60 template <typename T>
TypeName()61 inline constexpr std::string_view TypeName() {
62   return internal::ExtractName(internal::CompileTimeTypeName<T>::PrettyFn());
63 }
64 
65 static_assert(TypeName<int>() == "int");
66 
67 template <auto T>
ValueName()68 inline constexpr std::string_view ValueName() {
69   return internal::ExtractName(internal::CompileTimeValueName<T>::PrettyFn());
70 }
71 
72 // static_assert(ValueName<5>() == "5");
73 
74 }  // namespace cuttlefish
75