Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-16 09:44:28

0001 
0002 // Copyright 2020, Jefferson Science Associates, LLC.
0003 // Subject to the terms in the LICENSE file found in the top-level directory.
0004 
0005 #pragma once
0006 #include <cstdint>
0007 #include <cxxabi.h>
0008 #include <string>
0009 
0010 namespace JTypeInfo {
0011 
0012 #if __cplusplus >= 201703L
0013 template <typename, typename=void>
0014 struct is_parseable : std::false_type {};
0015 
0016 template <typename T>
0017 struct is_parseable<T, std::void_t<decltype(std::declval<std::istream>() >> std::declval<T&>())>> : std::true_type {};
0018 
0019 template <typename, typename=void>
0020 struct is_serializable : std::false_type {};
0021 
0022 template <typename T>
0023 struct is_serializable<T, std::void_t<decltype(std::declval<std::ostream>() << std::declval<T>())>> : std::true_type {};
0024 #endif
0025 
0026 
0027 template<typename T>
0028 std::string demangle() {
0029 
0030     /// Return the demangled name (if available) for the type the template
0031     /// is based. Call it like this:
0032     ///   cout << demangle<MyType>() << endl;
0033     int status = -1;
0034     auto cstr = abi::__cxa_demangle(typeid(T).name(), NULL, NULL, &status);
0035     std::string type(cstr);
0036     free(cstr);
0037     if (status != 0) type = typeid(T).name();
0038     return type;
0039 }
0040 
0041 
0042 inline std::string demangle_current_exception_type() {
0043 
0044     int status = -1;
0045     auto cstr = abi::__cxa_demangle(abi::__cxa_current_exception_type()->name(), NULL, NULL, &status);
0046     std::string type(cstr);
0047     free(cstr);
0048     if (status != 0) type = abi::__cxa_current_exception_type()->name();
0049     return type;
0050 }
0051 
0052 /// Macro for conveniently turning a variable name into a string. This is used by JObject::Summarize
0053 /// in order to play nicely with refactoring tools. Because the symbol is picked up by the
0054 /// preprocessor and not the compiler, no demangling is necessary.
0055 #define NAME_OF(T) #T
0056 
0057 
0058 /// Macro for extracting the typename of the current class as a std::string.
0059 /// This is meant to be used like this:
0060 /// `JEventProcessor::SetName(NAME_OF_THIS);`
0061 #define NAME_OF_THIS JTypeInfo::demangle<decltype(*this)>()
0062 
0063 
0064 template<typename T>
0065 const char* builtin_typename() {
0066     /// Function template for stringifying builtin typenames.
0067     /// This provides some normalization, i.e. both ulongs and uint64_t's get converted to "ulong"
0068 
0069     if (typeid(T) == typeid(int) || typeid(T) == typeid(int32_t)) {
0070         return "int";
0071     } else if (typeid(T) == typeid(unsigned int) || typeid(T) == typeid(uint32_t)) {
0072         return "uint";
0073     } else if (typeid(T) == typeid(long) || typeid(T) == typeid(int64_t)) {
0074         return "long";
0075     } else if (typeid(T) == typeid(unsigned long) || typeid(T) == typeid(uint64_t)) {
0076         return "ulong";
0077     } else if (typeid(T) == typeid(short) || typeid(T) == typeid(int16_t)) {
0078         return "short";
0079     } else if (typeid(T) == typeid(unsigned short) || typeid(T) == typeid(uint16_t)) {
0080         return "ushort";
0081     } else if (typeid(T) == typeid(float)) {
0082         return "float";
0083     } else if (typeid(T) == typeid(double)) {
0084         return "double";
0085     } else if (typeid(T) == typeid(std::string) || typeid(T) == typeid(const char*) || typeid(T) == typeid(char*)) {
0086         return "string";
0087     } else {
0088         return "unknown";
0089     }
0090 };
0091 
0092 inline std::string to_string_with_si_prefix(float val) {
0093 
0094     /// Return the value as a string with the appropriate latin unit prefix appended.
0095     /// Values returned are: "G", "M", "k", "", "u", and "m" for values of "val" that are:
0096     /// >1.5E9, >1.5E6, >1.5E3, <1.0E-7, <1.0E-4, 1.0E-1, respectively.
0097 
0098     const char* units = "";
0099     if (val > 1.5E9) {
0100         val /= 1.0E9;
0101         units = "G";
0102     } else if (val > 1.5E6) {
0103         val /= 1.0E6;
0104         units = "M";
0105     } else if (val > 1.5E3) {
0106         val /= 1.0E3;
0107         units = "k";
0108     } else if (val < 1.0E-7) {
0109         units = "";
0110     } else if (val < 1.0E-4) {
0111         val *= 1.0E6;
0112         units = "u";
0113     } else if (val < 1.0E-1) {
0114         val *= 1.0E3;
0115         units = "m";
0116     }
0117     char str[256];
0118     snprintf(str, 256, "%3.1f %s", val, units);
0119     return std::string(str);
0120 }
0121 
0122 
0123 } // namespace JTypeInfo