File: Float.h

package info (click to toggle)
edb-debugger 1.3.0-2.2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,124 kB
  • sloc: cpp: 46,241; xml: 4,998; ansic: 3,088; sh: 52; asm: 33; makefile: 5
file content (53 lines) | stat: -rw-r--r-- 1,212 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

#ifndef UTIL_FLOAT_H_2020227_
#define UTIL_FLOAT_H_2020227_

#include "FloatX.h"
#include <boost/optional.hpp>
#include <cerrno>
#include <string>
#include <type_traits>

namespace util {

template <typename Float>
boost::optional<Float> full_string_to_float(const std::string &s) {

	static_assert(
		std::is_same<Float, float>::value ||
			std::is_same<Float, double>::value ||
			std::is_same<Float, long double>::value,
		"Floating-point type not supported by this function");

	// NOTE: Don't use std::istringstream: it doesn't support hexfloat.
	//       Don't use std::sto{f,d,ld} either: they throw std::out_of_range on denormals.
	//       Only std::strto{f,d,ld} are sane, for some definitions of sane...
	const char *const str = s.c_str();
	char *end;
	Float value;
	errno = 0;

	if (std::is_same<Float, float>::value) {
		value = std::strtof(str, &end);
	} else if (std::is_same<Float, double>::value) {
		value = std::strtod(str, &end);
	} else {
		value = std::strtold(str, &end);
	}

	if (errno) {
		if ((errno == ERANGE && (value == 0 || std::isinf(value))) || errno != ERANGE) {
			return boost::none;
		}
	}

	if (end == str + s.size()) {
		return value;
	}

	return boost::none;
}

}

#endif