File indexing completed on 2024-04-06 12:01:17
0001 #ifndef CommonTools_Utils_AnyMethodArgument_h
0002 #define CommonTools_Utils_AnyMethodArgument_h
0003
0004 #include "FWCore/Reflection/interface/TypeWithDict.h"
0005 #include "FWCore/Utilities/interface/TypeID.h"
0006 #include "CommonTools/Utils/interface/parser/Exception.h"
0007
0008 #include <algorithm>
0009 #include <cstdint>
0010 #include <string>
0011 #include <type_traits>
0012 #include <variant>
0013
0014 namespace reco {
0015 namespace parser {
0016
0017
0018
0019 template <typename T>
0020 struct matches_another_integral_type {
0021 static bool const value = std::is_same<T, int8_t>::value || std::is_same<T, uint8_t>::value ||
0022 std::is_same<T, int16_t>::value || std::is_same<T, uint16_t>::value ||
0023 std::is_same<T, int32_t>::value || std::is_same<T, uint32_t>::value ||
0024 std::is_same<T, int64_t>::value || std::is_same<T, uint64_t>::value;
0025 };
0026
0027
0028
0029
0030
0031 typedef std::conditional<
0032 matches_another_integral_type<unsigned long>::value,
0033 std::variant<int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t, double, float, std::string>,
0034 std::variant<int8_t,
0035 uint8_t,
0036 int16_t,
0037 uint16_t,
0038 int32_t,
0039 uint32_t,
0040 int64_t,
0041 uint64_t,
0042 unsigned long,
0043 double,
0044 float,
0045 std::string> >::type AnyMethodArgument;
0046
0047 class AnyMethodArgumentFixup {
0048 private:
0049 edm::TypeWithDict dataType_;
0050 template <typename From, typename To>
0051 std::pair<AnyMethodArgument, int> retOk_(const From &f, int cast) const {
0052 return std::pair<AnyMethodArgument, int>(AnyMethodArgument(static_cast<To>(f)), cast);
0053 }
0054
0055
0056 std::pair<AnyMethodArgument, int> doInt(int t) const {
0057 if (dataType_ == typeid(int8_t)) {
0058 return retOk_<int, int8_t>(t, 0);
0059 }
0060 if (dataType_ == typeid(uint8_t)) {
0061 return retOk_<int, uint8_t>(t, 0);
0062 }
0063 if (dataType_ == typeid(int16_t)) {
0064 return retOk_<int, int16_t>(t, 0);
0065 }
0066 if (dataType_ == typeid(uint16_t)) {
0067 return retOk_<int, uint16_t>(t, 0);
0068 }
0069 if (dataType_ == typeid(int32_t)) {
0070 return retOk_<int, int32_t>(t, 0);
0071 }
0072 if (dataType_ == typeid(uint32_t)) {
0073 return retOk_<int, uint32_t>(t, 0);
0074 }
0075 if (dataType_ == typeid(int64_t)) {
0076 return retOk_<int, int64_t>(t, 0);
0077 }
0078 if (dataType_ == typeid(uint64_t)) {
0079 return retOk_<int, uint64_t>(t, 0);
0080 }
0081 if (dataType_ == typeid(unsigned long)) {
0082 return retOk_<int, unsigned long>(t, 0);
0083 }
0084 if (dataType_ == typeid(double)) {
0085 return retOk_<int, double>(t, 1);
0086 }
0087 if (dataType_ == typeid(float)) {
0088 return retOk_<int, float>(t, 1);
0089 }
0090 return std::pair<AnyMethodArgument, int>(t, -1);
0091 }
0092
0093 public:
0094 AnyMethodArgumentFixup(const edm::TypeWithDict &type) : dataType_(type) {}
0095
0096
0097 template <typename I>
0098 typename std::enable_if<std::is_integral<I>::value, std::pair<AnyMethodArgument, int> >::type operator()(
0099 const I &t) const {
0100 return doInt(t);
0101 }
0102
0103 template <typename F>
0104 typename std::enable_if<std::is_floating_point<F>::value, std::pair<AnyMethodArgument, int> >::type operator()(
0105 const F &t) const {
0106 if (dataType_ == typeid(double)) {
0107 return retOk_<F, double>(t, 0);
0108 }
0109 if (dataType_ == typeid(float)) {
0110 return retOk_<F, float>(t, 0);
0111 }
0112 return std::pair<AnyMethodArgument, int>(t, -1);
0113 }
0114
0115 std::pair<AnyMethodArgument, int> operator()(const std::string &t) const {
0116 if (dataType_.isEnum()) {
0117 if (dataType_.dataMemberSize() == 0) {
0118 throw parser::Exception(t.c_str())
0119 << "Enumerator '" << dataType_.name() << "' has no keys.\nPerhaps the dictionary is missing?\n";
0120 }
0121 int ival = dataType_.stringToEnumValue(t);
0122
0123 return std::pair<AnyMethodArgument, int>(ival, 1);
0124 }
0125 if (dataType_ == typeid(std::string)) {
0126 return std::pair<AnyMethodArgument, int>(t, 0);
0127 }
0128 return std::pair<AnyMethodArgument, int>(t, -1);
0129 }
0130 };
0131
0132 class AnyMethodArgument2VoidPtr {
0133 public:
0134 template <typename T>
0135 void *operator()(const T &t) const {
0136 return const_cast<void *>(static_cast<const void *>(&t));
0137 }
0138 };
0139 }
0140 }
0141
0142 #endif