libcppwrap
A collection of C++ wrappers for native APIs
Loading...
Searching...
No Matches
string.hpp
Go to the documentation of this file.
1//
2// libcppwrap - A collection of C++ wrappers for native APIs
3// Copyright (C) 2021-2023 David A. Norris <danorris@gmail.com>
4// Published under the MIT license - https://opensource.org/licenses/MIT
5//
6
7#pragma once
8
9#include <algorithm>
10#include <cctype>
11#include <cerrno>
12#include <cstdlib>
13#include <limits>
14#include <stdexcept>
15#include <string>
16#include <type_traits>
17
18namespace wx
19{
30 template <typename T>
31 typename std::enable_if<std::is_integral_v<T> && std::is_unsigned_v<T>, T>::type
32 number(const char *str, int base = 10)
33 {
34 char *end;
35 errno = 0;
36 unsigned long long l = std::strtoull(str, &end, base);
37 if (end == str || *end)
38 throw std::runtime_error("invalid numeric string");
39 else if (l > std::numeric_limits<T>::max() || (l == std::numeric_limits<unsigned long long>::max() && errno == ERANGE))
40 throw std::range_error("number is out of range");
41 return l;
42 }
43
47 template <typename T>
48 typename std::enable_if<std::is_integral_v<T> && std::is_signed_v<T>, T>::type
49 number(const char *str, int base = 10)
50 {
51 char *end;
52 errno = 0;
53 long long l = std::strtoll(str, &end, base);
54 if (end == str || *end)
55 throw std::runtime_error("invalid numeric string");
56 else if (l > std::numeric_limits<T>::max() || (l == std::numeric_limits<long long>::max() && errno == ERANGE))
57 throw std::range_error("number is out of range");
58 else if (l < std::numeric_limits<T>::min() || (l == std::numeric_limits<long long>::min() && errno == ERANGE))
59 throw std::range_error("number is out of range");
60 return l;
61 }
62
72 template <typename T>
74 number(const char *str)
75 {
76 char *end;
77 errno = 0;
78 double d = std::strtod(str, &end);
79 if (end == str || *end)
80 throw std::runtime_error("invalid numeric string");
81 else if (errno == ERANGE)
82 throw std::range_error("number is out of range");
83 return d;
84 }
85
89 template <typename T>
91 number(const std::string& str, int base = 10)
92 {
93 return number<T>(str.c_str(), base);
94 }
95
105 template <typename T>
107 number(const std::string& str)
108 {
109 return number<T>(str.c_str());
110 }
111
118 static inline std::string& rtrim(std::string& str) noexcept
119 {
120 auto from = std::find_if(
121 str.rbegin(),
122 str.rend(),
123 [](unsigned char ch) { return !std::isspace(ch) && ch != '\0'; });
124
125 str.erase(from.base(), str.end());
126
127 return str;
128 }
129}
T c_str(T... args)
T find_if(T... args)
Definition: ipv6.hpp:14
static std::string & rtrim(std::string &str) noexcept
Removes trailing whitespace from a string in-place.
Definition: string.hpp:118
std::enable_if< std::is_integral_v< T > &&std::is_unsigned_v< T >, T >::type number(const char *str, int base=10)
Parses a string as a numeric value with strict formatting and range checks.
Definition: string.hpp:32
auto end(const struct ifaddrs *ptr) noexcept
Returns an input iterator pointing to the end of a struct ifaddrs array.
Definition: sockets.hpp:537
T strtod(T... args)
T strtoll(T... args)
T strtoull(T... args)