The Sparta Modeling Framework
Loading...
Searching...
No Matches
LexicalCast.hpp
Go to the documentation of this file.
1// <LexicalCast.hpp> -*- C++ -*-
2
3#pragma once
4
5#include <cstdlib>
6#include <iostream>
7#include <math.h>
8#include <typeinfo>
9#include <bitset>
10#include <string>
11
15
16
17// For YAML converter (bool string -> bool)
18#include <yaml-cpp/node/node.h>
19#include <yaml-cpp/node/convert.h>
20
26#if defined(__clang__)
27// for LLVM/clang
28namespace std
29{
30 template <typename _Cp, bool>
31 class __bit_reference;
32}
33#else
34// for gcc/icc
35namespace std
36{
37 struct _Bit_reference;
38}
39#endif
40
41namespace sparta
42{
43
49 template <typename T>
51 typedef T type;
52 };
53
54#if !defined(__linux__) && defined(__llvm__)
55 template <typename _Cp>
56 struct bit_reference_to_bool<std::__1::__bit_reference<_Cp> > {
57 typedef bool type;
58 };
59#else
60 template <>
61 struct bit_reference_to_bool<typename std::_Bit_reference> {
62 typedef bool type;
63 };
64#endif
65
78 template <class T>
79 inline T lexicalCast(const std::string& str, uint32_t base=10) {
80 (void) base;
81 T tmp;
82 std::stringstream ss;
83 ss << str;
84 ss >> tmp;
85 if(ss.fail() == false) {
86 return tmp;
87 }
88
89 SpartaException ex("Unable to cast string \"");
90 ex << str << "\" to typeid: \"" << typeid(T).name() << "\"";
91 throw ex;
92 }
93
94 template <class T>
95 inline MetaStruct::enable_if_t<MetaStruct::is_stl<T>::value and
96 std::is_same<typename T::value_type, bool>::value, T>
97 lexicalCast(const std::string& str, uint32_t base = 10) = delete;
98
99 template <>
100 inline std::string lexicalCast(const std::string& str, uint32_t base) {
101 (void) base;
102 return str;
103 }
104
105 template <>
106 inline bool lexicalCast(const std::string& str, uint32_t base) {
107 (void) base;
108 bool out;
109 YAML::Node node(YAML::NodeType::Scalar);
110 node = str;
111
112 // Handles conversion of YAML booleans literals like on/off,
113 // yes/no, etc. We're cheating here and using code already
114 // written and tested. Hopefully Jesse Beder doesn't change
115 // it on us again. LOL
116 if(false == YAML::convert<bool>::decode(node, out)){
117 int out_int;
118 if(false == YAML::convert<int>::decode(node, out_int)){ // Fall back to 1/0 support
119 SpartaException ex("Unable to cast string \"");
120 ex << str << "\" to bool";
121 throw ex;
122 }else{
123 out = out_int != 0;
124 }
125 }
126 return out;
127 }
128
129 template <>
130 inline uint64_t lexicalCast(const std::string& str, uint32_t base) {
131 try {
132 uint64_t val = std::stoul(str.c_str(), nullptr, base);
133 return val;
134 }
135 catch(std::exception &e) {
136 SpartaException ex("Unable to cast string \"");
137 ex << str << "\" to uint64_t: " << e.what();
138 throw ex;
139 }
140 return 0;
141 }
142
143 template <>
144 inline int64_t lexicalCast(const std::string& str, uint32_t base) {
145 try {
146 int64_t val = std::stol(str.c_str(), nullptr, base);
147 return val;
148 }
149 catch(std::exception &e) {
150 SpartaException ex("Unable to cast string \"");
151 ex << str << "\" to int64_t: " << e.what();
152 throw ex;
153 }
154 return 0;
155 }
156
157 template <>
158 inline uint32_t lexicalCast(const std::string& str, uint32_t base) {
159 try {
160 // There is no conversation of a string to a 32-bit unsigned in C/C++
161 uint64_t val = std::stoul(str.c_str(), nullptr, base);
162 if (val > std::numeric_limits<uint32_t>::max()) {
163 throw std::range_error("Value " + str + " is too large to fit into a uint32_t");;
164 }
165 return static_cast<uint32_t>(val);
166 }
167 catch(std::exception &e) {
168 SpartaException ex("Unable to cast string \"");
169 ex << str << "\" to uint32_t: " << e.what();
170 throw ex;
171 }
172 return 0;
173 }
174
175 template <>
176 inline int32_t lexicalCast(const std::string& str, uint32_t base) {
177 try {
178 int32_t val = std::stoi(str.c_str(), nullptr, base);
179 return val;
180 }
181 catch(std::exception &e) {
182 SpartaException ex("Unable to cast string \"");
183 ex << str << "\" to int32_t: " << e.what();
184 throw ex;
185 }
186 return 0;
187 }
188
190 inline uint32_t numDecDigits(uint32_t val){
191 if(val <= 1){
192 return 1;
193 }
194 return 1 + floor(log10(val));
195 }
196
197} // namespace sparta
Contains a collection implementation of various compile-time metaprogramming and Type-Detection APIs ...
Set of macros for Sparta assertions. Caught by the framework.
Exception class for all of Sparta.
Used to construct and throw a standard C++ exception. Inherits from std::exception.
Macros for handling exponential backoff.
uint32_t numDecDigits(uint32_t val)
Gets number of decimal digits in a uint32_t.
T lexicalCast(const std::string &str, uint32_t base=10)
Helper type for converting _Bit_reference types into bool types for the purpose of determining how to...