dbg.h 模板部分源码 的部分 代码阅读记录


inline bool isColorizedOutputEnabled() {
#if defined(DBG_MACRO_FORCE_COLOR)
  return true;
#elif defined(DBG_MACRO_UNIX)
  return isatty(fileno(stderr));
#else
  return true;
#endif
}

struct time {};

namespace pretty_function {

// Compiler-agnostic version of __PRETTY_FUNCTION__ and constants to
// extract the template argument in `type_name_impl`
// __PRETTY_FUNCTION__ 就是更完整的函数信息,包括参数等
#if defined(__clang__)
#define DBG_MACRO_PRETTY_FUNCTION __PRETTY_FUNCTION__
static constexpr size_t PREFIX_LENGTH =
    sizeof("const char *dbg::type_name_impl() [T = ") - 1;
static constexpr size_t SUFFIX_LENGTH = sizeof("]") - 1;
#elif defined(__GNUC__) && !defined(__clang__)
#define DBG_MACRO_PRETTY_FUNCTION __PRETTY_FUNCTION__
static constexpr size_t PREFIX_LENGTH =
    sizeof("const char* dbg::type_name_impl() [with T = ") - 1;
static constexpr size_t SUFFIX_LENGTH = sizeof("]") - 1;
#elif defined(_MSC_VER)
#define DBG_MACRO_PRETTY_FUNCTION __FUNCSIG__
static constexpr size_t PREFIX_LENGTH =
    sizeof("const char *__cdecl dbg::type_name_impl<") - 1;
static constexpr size_t SUFFIX_LENGTH = sizeof(">(void)") - 1;
#else
#error "This compiler is currently not supported by dbg_macro."
#endif

}  // namespace pretty_function

// Formatting helpers

template 
struct print_formatted {
  static_assert(std::is_integral::value,
                "Only integral types are supported.");

  print_formatted(T value, int numeric_base)
      : inner(value), base(numeric_base) {}

  operator T() const { return inner; }

  const char* prefix() const {
    switch (base) {
      case 8:
        return "0o";
      case 16:
        return "0x";
      case 2:
        return "0b";
      default:
        return "";
    }
  }

  T inner;
  int base;
};

template 
print_formatted hex(T value) {
  return print_formatted{value, 16};
}

template 
print_formatted oct(T value) {
  return print_formatted{value, 8};
}

template 
print_formatted bin(T value) {
  return print_formatted{value, 2};
}

// Implementation of 'type_name()'

template 
const char* type_name_impl() {
  return DBG_MACRO_PRETTY_FUNCTION;
}

//应该无意义,只是为了get_type_name传参占位
template 
struct type_tag {};

/*
int&... ExplicitArgumentBarrier  变长参数模板,,可以禁止用户显示指定模板参数
不能这样 get_type_name(???)
只能这样 get_type_name(???)

std::rank 如果是数组类型,value 为 数组维数
std::enable_if::type 如果满足条件 type 为 std::string; 如果不满足 则编译错误
typename std::enable_if<(std::rank::value == 0), std::string>::type  : 函数返回值,即如果T 是非数组类型,则定义如下, 否则编译错误
std::string get_type_name(type_tag){
    //...
}
*/

template 
typename std::enable_if<(std::rank::value == 0), std::string>::type
get_type_name(type_tag) {
  namespace pf = pretty_function;

  std::string type = type_name_impl();
  return type.substr(pf::PREFIX_LENGTH,
                     type.size() - pf::PREFIX_LENGTH - pf::SUFFIX_LENGTH);
}

/*
获取 T 类型名称 ,递归调用展开的
*/
template 
std::string type_name() {
  if (std::is_volatile::value) {
    if (std::is_pointer::value) {
      return type_name::type>() + " volatile";
    } else {
      return "volatile " + type_name::type>();
    }
  }
  if (std::is_const::value) {
    if (std::is_pointer::value) {
      return type_name::type>() + " const";
    } else {
      return "const " + type_name::type>();
    }
  }
  if (std::is_pointer::value) {
    return type_name::type>() + "*";
  }
  if (std::is_lvalue_reference::value) {
    return type_name::type>() + "&";
  }
  if (std::is_rvalue_reference::value) {
    return type_name::type>() + "&&";
  }
  return get_type_name(type_tag{});
}

//对于一些基本类型的特化版本
// Prefer bitsize variant over standard integral types
#define DBG_MACRO_REGISTER_TYPE_ASSOC(t_std, t_bit)             \
  inline constexpr const char* get_type_name(type_tag) { \
    return std::is_same::value ? #t_bit : #t_std; \
  }

DBG_MACRO_REGISTER_TYPE_ASSOC(unsigned char, uint8_t)
DBG_MACRO_REGISTER_TYPE_ASSOC(unsigned short, uint16_t)
DBG_MACRO_REGISTER_TYPE_ASSOC(unsigned int, uint32_t)
DBG_MACRO_REGISTER_TYPE_ASSOC(unsigned long, uint64_t)
DBG_MACRO_REGISTER_TYPE_ASSOC(signed char, int8_t)
DBG_MACRO_REGISTER_TYPE_ASSOC(short, int16_t)
DBG_MACRO_REGISTER_TYPE_ASSOC(int, int32_t)
DBG_MACRO_REGISTER_TYPE_ASSOC(long, int64_t)

//对 std::string  的特化
inline std::string get_type_name(type_tag) {
  return "std::string";
}


template 
typename std::enable_if<(std::rank::value == 1), std::string>::type
get_array_dim() {
  return "[" + std::to_string(std::extent::value) + "]";
}

template 
typename std::enable_if<(std::rank::value > 1), std::string>::type
get_array_dim() {
  return "[" + std::to_string(std::extent::value) + "]" +
         get_array_dim::type>();
}

//对数组类型的特化 ,结合上面两个模板函数可以处理 N维数组类型
template 
typename std::enable_if<(std::rank::value > 0), std::string>::type
get_type_name(type_tag) {
  return type_name::type>() + get_array_dim();
}

//下面都是对部分特殊类型的特化处理
template 
std::string get_type_name(type_tag>) {
  return "std::array<" + type_name() + ", " + std::to_string(N) + ">";
}

template 
std::string get_type_name(type_tag>>) {
  return "std::vector<" + type_name() + ">";
}

template 
std::string get_type_name(type_tag>) {
  return "std::pair<" + type_name() + ", " + type_name() + ">";
}

template 
std::string type_list_to_string() {
  std::string result;
  auto unused = {(result += type_name() + ", ", 0)..., 0};
  static_cast(unused);

#if DBG_MACRO_CXX_STANDARD >= 17
  if constexpr (sizeof...(T) > 0) {
#else
  if (sizeof...(T) > 0) {
#endif
    result.pop_back();
    result.pop_back();
  }
  return result;
}

template 
std::string get_type_name(type_tag>) {
  return "std::tuple<" + type_list_to_string() + ">";
}

template 
inline std::string get_type_name(type_tag>) {
  return type_name();
}

// Implementation of 'is_detected' to specialize for container-like types

namespace detail_detector {

//空类,
struct nonesuch {
  nonesuch() = delete;
  ~nonesuch() = delete;
  nonesuch(nonesuch const&) = delete;
  void operator=(nonesuch const&) = delete;
};

//功能:能够检测到应用SFINAE(替换失败并不是一个错误)特性时出现的非法类型。换句话说,给进来的类型 _Types 必须是一个有效的类型,不能是一个非法类型。
//深入了解SFINAE
template 
using void_t = void;

//is_detected的作用是判断Op这样的表述是否能通过编译。如果通过编译value_t = std::true_type否则value_t = std::false_type

template 
          class Op,
          class... Args>
struct detector {
  using value_t = std::false_type;
  using type = Default;
};

template  class Op, class... Args>
struct detector>, Op, Args...> {
  using value_t = std::true_type;
  using type = Op;
};

}  // namespace detail_detector

template