/
githubmirror
/
CPlusPlusThings
Обзор
Документация
Войти
/
githubmirror
/
CPlusPlusThings
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
learn_class/modern_cpp_30/constexpr/output_container.h
134 строки
4 KB
zhangxing
support bazel complie this project and format code.
30 мар 2024, 17:00
30 мар 2024, 17:00
3c8a3f2
Код
Авторство
О чём код?
// // Created by light on 20-1-8. // #ifndef MORDEN_C_OUTPUT_CONTAINER_H #define MORDEN_C_OUTPUT_CONTAINER_H #include <ostream> // std::ostream #include <type_traits> // std::false_type/true_type/decay_t/is_same_v #include <utility> // std::declval/pair // 检测是否是pair template <typename T> struct is_pair : std::false_type {}; template <typename T, typename U> struct is_pair<std::pair<T, U>> : std::true_type {}; template <typename T> inline constexpr bool is_pair_v = is_pair<T>::value; // 检测是否可以直接输出 template <typename T> struct has_output_function { template <class U> static auto output(U *ptr) -> decltype(std::declval<std::ostream &>() << *ptr, std::true_type()); template <class U> static std::false_type output(...); static constexpr bool value = decltype(output<T>(nullptr))::value; }; template <typename T> inline constexpr bool has_output_function_v = has_output_function<T>::value; enum CHARS { ORD, // 其他类型 CHAR, // char 类型 STRING // string 类型 }; template <typename T> int ischarOrString(T &elem) { using std::decay_t; using std::is_same_v; using element_type = decay_t<decltype(elem)>; constexpr bool is_char_v = is_same_v<element_type, char>; constexpr bool is_string_v = is_same_v<element_type, char *> || is_same_v<element_type, const char *> || is_same_v<element_type, std::string>; if (is_char_v) return CHAR; else if (is_string_v) return STRING; else return ORD; } template <typename T> void output(T &elem, int type, std::ostream &os) { switch (type) { case CHAR: os << '\'' << elem << '\''; break; case STRING: os << '\"' << elem << '\"'; break; case ORD: os << elem; break; } } template <typename T, typename Cont> auto output_element(std::ostream &os, const T &element, const Cont &) -> typename std::enable_if<is_pair<typename Cont::value_type>::value, bool>::type { int ftype = ischarOrString(element.first); int stype = ischarOrString(element.second); output(element.first, ftype, os); os << " => "; output(element.second, stype, os); return true; } template <typename T, typename Cont> auto output_element(std::ostream &os, const T &element, const Cont &) -> typename std::enable_if<!is_pair<typename Cont::value_type>::value, bool>::type { int etype = ischarOrString(element); output(element, etype, os); return false; } template <typename T, typename U> std::ostream &operator<<(std::ostream &os, const std::pair<T, U> &pr) { os << '(' << pr.first << ", " << pr.second << ')'; return os; } // template<typename T, typename Cont> // auto output_element(std::ostream& os, const T& element, // const Cont&, const std::true_type) //-> decltype(std::declval<typename Cont::key_type>(), os) //{ // os << element.first << " => " << element.second; // return os; // } // // template <typename T, typename Cont> // auto output_element(std::ostream& os, const T& element, // const Cont&, ...) //-> decltype(os) //{ // os << element; // return os; // } // 针对没有输出函数的容器处理 template <typename T, typename = std::enable_if_t<!has_output_function_v<T>>> auto operator<<(std::ostream &os, const T &container) -> decltype(container.begin(), container.end(), os) { os << "{ "; if (!container.empty()) { bool on_first_element = true; for (auto elem : container) { if (!on_first_element) { os << ", "; } else { on_first_element = false; } output_element(os, elem, container); } } os << " }"; return os; } #endif // MORDEN_C_OUTPUT_CONTAINER_H