aboutsummaryrefslogtreecommitdiff
path: root/include/openvic-dataloader/detail/TypeName.hpp
blob: 1a34a0fd076a237a12b372c944b9523831784d31 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#pragma once

#include <array>
#include <cstddef>
#include <string_view>
#include <utility>

namespace ovdl::detail {

   template<std::size_t... Idxs>
   constexpr auto substring_as_array(std::string_view str, std::index_sequence<Idxs...>) {
      return std::array { str[Idxs]... };
   }

   template<typename T>
   constexpr auto type_name_array() {
#if defined(__clang__)
      constexpr auto prefix = std::string_view { "[T = " };
      constexpr auto suffix = std::string_view { "]" };
      constexpr auto function = std::string_view { __PRETTY_FUNCTION__ };
#elif defined(__GNUC__)
      constexpr auto prefix = std::string_view { "with T = " };
      constexpr auto suffix = std::string_view { "]" };
      constexpr auto function = std::string_view { __PRETTY_FUNCTION__ };
#elif defined(_MSC_VER)
      constexpr auto prefix = std::string_view { "type_name_array<" };
      constexpr auto suffix = std::string_view { ">(void)" };
      constexpr auto function = std::string_view { __FUNCSIG__ };
#else
#error Unsupported compiler
#endif

      constexpr auto start = function.find(prefix) + prefix.size();
      constexpr auto end = function.rfind(suffix);

      static_assert(start < end);

      constexpr auto name = function.substr(start, (end - start));
      return substring_as_array(name, std::make_index_sequence<name.size()> {});
   }

   template<typename T>
   struct type_name_holder {
      static inline constexpr auto value = type_name_array<T>();
   };

   template<typename T>
   constexpr auto type_name() -> std::string_view {
      constexpr auto& value = type_name_holder<T>::value;
      return std::string_view { value.data(), value.size() };
   }
}