Given a variable defined as
T x;
where T is a generic arithmetic type (i.e. such that std::is_arithmetic<T>::value), is there a simple expression (e.g something from std::numeric_limits) that evaluates to the lowest value y expressible in T such that y > x?
(i.e. a kind of generalized increment..)
You can use std::nextafter.
Note that here I use std::numeric_limits<Floating>::max(), if you want meaningful behavior for infinities, you might want to modify the code.
#include <iostream>
#include <limits>
#include <cmath>
#include <type_traits>
#include <iomanip>
template <typename Floating,
std::enable_if_t<std::is_arithmetic_v<Floating> && !std::is_integral_v<Floating>, bool> = false>
Floating generic_next_val(Floating val) {
return std::nextafter(val, std::numeric_limits<Floating>::max());
}
template <typename Integral,
std::enable_if_t<std::is_arithmetic_v<Integral> && std::is_integral_v<Integral>, int> = 0>
Integral generic_next_val(Integral val) {
return static_cast<Integral>(val + static_cast<Integral>(1));
}
int main() {
int a = 1;
float f = 0.0f;
std::cout << std::setprecision(20) << generic_next_val(f) << " " << generic_next_val(a) << std::endl;
return 0;
}
The <cmath> header's std::nexttoward() will do this. It accepts a float, double, long double, or integral type, and returns the next value in the direction of its second parameter.
So, given code like this:
T my_val = some_input; // float, double, int, etc.
T next = std::nexttoward(my_val, std::numeric_limits<T>::max());`
If my_val were 1.0f, next would be the next biggest float after 1; if my_val were the integer 2, you would get 3, etc.
(Note that there's a lot of fine print here around numeric overflows, which the CppReference page linked above discusses. The long and short of it is don't pass std::numeric_limits<T>::max() in for the first parameter.)
#include <type_traits>
#include <limits>
#include <iostream>
/*
NOTE: Untested code for 'proof' of concept only.
This will cover all the is_integral<T> except bool.
This should probably be a set of free functions rather than a class
but just to check out the idea. Class should have constraints but as
the final implementation should probably be free functions they are
omitted.
*/
template<typename T>
class GLB{
public:
using limits = std::numeric_limits<T>;
static T get(const T& value){
return value == limits::max() ? limits::max() : value + static_cast<T>(1);
}
};
int main(int, char**){
std::cout << GLB<int>::get(42) << '\n';
std::cout << GLB<unsigned>::get(42) << '\n';
std::cout << GLB<wchar_t>::get(42) << '\n';
return 0;
}
/*
That was the easy bit now what about the floating point numbers.
*/
While fooling around with this scur3 pointed out that cmath can solve the floating point values. So some typing and some testing required.
Related
std::bit_cast in C++20 is a safer version of reinterpret_cast that works with constexpr so I read, but does that mean the actual value of the variable involved also gets reinterpreted bitwise? e.g. following simple code
#include <iostream>
#include <bit>
int main()
{
float f = 123.017;
auto f_int = std::bit_cast<int>(f);
std::cout << "f : " << f << ", f_int : " << f_int << std::endl;
}
produces this output
f : 123.017, f_int : 1123420340
I am trying to use std::bit_cast to safely reinterpret data type hoping to retain narrowing version of the original data value, which obviously didn't happen.
std::bit_cast is the same as memcpy, the bits of the original are the same as the converted value. You might be after static_cast:
#include <bit>
#include <stdio.h>
using namespace std;
int main()
{
float f = 123.017;
auto a = static_cast<int>(f);
auto b = std::bit_cast<int>(f);
printf("f: %f a: %d b: %d\n", f, a, b); // f: 123.016998 a: 123 b: 1123420340
return 0;
}
I am trying to make an optimal function that would accept compile-time constants and runtime constants, and do optimization at compile-time when the compiler knows the value. The problem is when I try to unpack the parameter pack it has to be moved into a runtime variable causing the compiler not to optimize in the same manner as if the constants was properly propagated. Unfortunately I'm not quite sure how to unpack to a single object while maintaining a mixture of compile-time and runtime variables in the same structure.
I have two working test cases: one that does what it suppose to do (assembly-wise), but is not generic with regards to parameter packs. The other does have a parameter packs, but the compiler loses the compile-time constant through the unpacking.
// Example program
#include <iostream>
#include <string>
#include <type_traits>
#include <functional>
#include <tuple>
struct ii{
int value;
};
template<int Val>
using tt = std::conditional_t<Val==0, ii, std::integral_constant<int, Val> >;
template<int... vals>
void foo( tt<vals>... inp)
{
const int arr[sizeof...(inp)] = {inp.value...};
std::cout << "parameter " << (16 / arr[0]) << std::endl; //<-incorrect asm
std::cout << "parameter " << (16/ arr[1] ) << std::endl; //expected asm
}
void check(ii i, std::integral_constant<int, 4> a)
{
std::cout << "i = " << ( 16 / i.value ) << std::endl; //<--expected asm
std::cout << "i = " << (16 / a.value ) << std::endl; //<--this is OK in asm
}
int main()
{
std::integral_constant<int, 4> four;
check(ii{1},four );
foo<four.value,0>(four, ii{1});
}
The expected results for "(16 / arr[0])" should be calculated at compile time, and it should be a constant 4.
Thank you!
When attempting to access a tuple's value via a scoped and typed enum, I get an error saying there is no matching type for std::get.
enum class User: std::size_t {
FirstName = 1,
LastName = 2,
};
std::tuple<std::string, std::string> user("Bobby", "Bean");
// Error
std::cout << std::get<User::FirstName>(user) << std::endl;
Given that std::get expects type std::size_t and the underlying type of the enum is also std::size_t, why does this fail?
I'm aware that I can cast the value of the enum, but I'm not sure why that would be necessary given that both underlying types are the same. With an unscoped enum, this works just fine.
Enum classes really aren't integers on the surface. Just like a struct containing just an int is not an int.
The C++ standard way back to the integer representation is this:
using UserUndT = std::underlying_type<User>::type;
std::cout <<
std::get<static_cast<UserUndT>(User::FirstName)>(user) << std::endl;
Also, check out this question: Using enable_if and underlying_type in function signature in VS2012
An alternative worth considering: (C++14)
#include <iostream>
#include <tuple>
struct FirstName {
std::string val;
};
struct LastName {
std::string val;
};
using FullName = std::tuple<FirstName,LastName>;
int main() {
auto user = FullName({"John"},{"Deer"});
std::cout << std::get<FirstName>(user).val << std::endl;
std::cout << std::get<LastName>(user).val << std::endl;
}
to get what you want you can do:
namespace User{enum User:size_t{FirstName,LastName};};
then you will have the bare typed enum again.
The namespace solution works but not inside a function or class. An alternative is as follows:
#include <iostream>
#include <tuple>
#include <vector>
#include <string>
using namespace std;
int main()
{
struct Test{enum size_t{first, second, third};};
vector<tuple<int, string, bool>> mt;
mt.emplace_back(make_tuple(10, "hello", true));
cout << get<Test::first>(mt[0]) << ' ' << get<Test::second>(mt[0]) << ' ' << get<Test::third>(mt[0]) << endl;
return 0;
}
How can I identify if the number is complex in C++?
Is there any built in function like this?:
isComplex(1)->false
C++ is a strongly typed language, and the literal 1 is always an int.
The determination you ask about might be relevant when converting text... isComplex("1"), for that you can attempt streaming:
std::istringstream iss(some_text);
std::complex<double> my_complex;
char c;
if (iss >> my_complex && // conversion possible...
!(iss >> c)) // no unconverted non-whitespace characters afterwards
...use my_complex...
else
throw std::runtime_error("input was not a valid complex number");
Separately, if you're inside a template and not sure whether a type parameter is std::complex, you can test with e.g. std::is_same<T, std::is_complex<double>>::value, for example:
#include <iostream>
#include <complex>
#include <type_traits>
using namespace std;
double get_real(double n) { return n; }
double get_real(const std::complex<double>& n) { return n.real(); }
template <typename T>
std::complex<double> f(T n)
{
if (std::is_same<T, std::complex<double>>::value)
return n * std::complex<double>{1, -1} + get_real(n);
else
return -n;
}
int main()
{
std::cout << f(std::complex<double>{10, 10}) << '\n';
std::cout << f(10.0) << '\n';
}
Output:
(30,0)
(-10,0)
See the code here.
For more complicated functions, you may want to create separate overloads for e.g. double and std::complex<double>, and/or float and std::complex<float>, long double etc..
In the ideal case, I would like to use the ClassVariant in the following way:
// store & retrieve int
map<string, ClassVariant> mapValues;
mapValues["int_fieldX"] = ClassVariant(20);
int fieldX = (mapValues["int_fieldX"])();
// Or int fieldX = (mapValues["int_fieldX"]);
However, I can ONLY implement the following code that requires the retrieving statement to feed the type info as follows:
int fieldB = (mapValuesTwo["int_fieldB"])(int(0));
As you can see int(0) is provided as type info. Is there a way that I can remove this limitation. So that the type info is NOT needed.
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <boost/variant.hpp>
using namespace std;
typedef boost::variant<int, double, string> VarIntDoubleString;
class ClassVariant
{
public:
ClassVariant() : m_value(int(0)) {}
ClassVariant(VarIntDoubleString _val) : m_value(_val) {}
template<typename T>
T operator()(const T&) const
{
return boost::get<T>(m_value);
}
private:
VarIntDoubleString m_value;
};
int main(void)
{
map<string, ClassVariant> mapValuesTwo;
// store & retrieve int
mapValuesTwo["int_fieldB"] = ClassVariant(20);
int fieldB = (mapValuesTwo["int_fieldB"])(int(0));
cout << "fieldB: " << fieldB << endl;
// store & retrieve string
mapValuesTwo["int_fieldD"] = ClassVariant("Hello world");
string fieldD = (mapValuesTwo["int_fieldD"])(string(""));
cout << "fieldD: " << fieldD << endl;
}
// Output
fieldB: 20
fieldD: Hello world
You can't do this, template argument deduction works only on the parameters, not on the return value of a function. Your best choice is to ditch operator() for a normal function like get<T>(). I can't point to the relevant line in the standard though, too obscure for me.
Note: if such a thing was possible, my guess would be that boost::variant would already have a get function where specifying T is not requried.
EDIT: see this question
You SHOULD use boost::variant together with visitor to access the value in it. see here