Are enums the canonical way to implement bit flags? - c++

Currently I'm using enums to represent a state in a little game experiment. I declare them like so:
namespace State {
enum Value {
MoveUp = 1 << 0, // 00001 == 1
MoveDown = 1 << 1, // 00010 == 2
MoveLeft = 1 << 2, // 00100 == 4
MoveRight = 1 << 3, // 01000 == 8
Still = 1 << 4, // 10000 == 16
Jump = 1 << 5
};
}
So that I can use them this way:
State::Value state = State::Value(0);
state = State::Value(state | State::MoveUp);
if (mState & State::MoveUp)
movement.y -= mPlayerSpeed;
But I'm wondering if this is the right way to implement bit flags. Isn't there a special container for bit flags? I heard about std::bitset, is it what I should use? Do you know something more efficient?
Am I doing it right?
I forgot to point out I was overloading the basic operators of my enum:
inline State::Value operator|(State::Value a, State::Value b)
{ return static_cast<State::Value>(static_cast<int>(a) | static_cast<int>(b)); }
inline State::Value operator&(State::Value a, State::Value b)
{ return static_cast<State::Value>(static_cast<int>(a) & static_cast<int>(b)); }
inline State::Value& operator|=(State::Value& a, State::Value b)
{ return (State::Value&)((int&)a |= (int)b); }
I had to use a C-style cast for the |=, it didn't work with a static_cast - any idea why?

The STL contains std::bitset, which you can use for precisely such a case.
Here is just enough code to illustrate the concept:
#include <iostream>
#include <bitset>
class State{
public:
//Observer
std::string ToString() const { return state_.to_string();};
//Getters
bool MoveUp() const{ return state_[0];};
bool MoveDown() const{ return state_[1];};
bool MoveLeft() const{ return state_[2];};
bool MoveRight() const{ return state_[3];};
bool Still() const{ return state_[4];};
bool Jump() const{ return state_[5];};
//Setters
void MoveUp(bool on) {state_[0] = on;}
void MoveDown(bool on) {state_[1] = on;}
void MoveLeft(bool on) {state_[2] = on;}
void MoveRight(bool on) {state_[3] = on;}
void Still(bool on) {state_[4] = on;}
void Jump(bool on) {state_[5] = on;}
private:
std::bitset<6> state_;
};
int main() {
State s;
auto report = [&s](std::string const& msg){
std::cout<<msg<<" "<<s.ToString()<<std::endl;
};
report("initial value");
s.MoveUp(true);
report("move up set");
s.MoveDown(true);
report("move down set");
s.MoveLeft(true);
report("move left set");
s.MoveRight(true);
report("move right set");
s.Still(true);
report("still set");
s.Jump(true);
report("jump set");
return 0;
}
Here's it working: http://ideone.com/XLsj4f
The interesting thing about this is that you get std::hash support for free, which is typically one of the things you would need when using state inside various data structures.
EDIT:
There is one limitation to std::bitset and that is the fact that you need to know the maximum number of bits in your bitset at compile time. However, that is the same case with enums anyway.
However, if you don't know the size of your bitset at compile time, you can use boost::dynamic_bitset, which according to this paper (see page 5) is actually really fast. Finally, according to Herb Sutter, std::bitset was designed to be used in cases you would normally want to use std::vector.
That said, there really is no substitute for real world tests. So if you really want to know, profile. That will give you performance numbers for a context that you care about.
I should also mention that std::bitset has an advantage that enum does not - there is no upper limit on the number of bits you can use. So std::bitset<1000> is perfectly valid.

I believe that your approach is right (except several things):
1. You can explicitly specify underlying type to save memory;
2. You can not use unspecified enum values.
namespace State {
enum Value : char {
None = 0,
MoveUp = 1 << 0, // 00001 == 1
MoveDown = 1 << 1, // 00010 == 2
MoveLeft = 1 << 2, // 00100 == 4
MoveRight = 1 << 3, // 01000 == 8
Still = 1 << 4, // 10000 == 16
Jump = 1 << 5
};
}
and:
State::Value state = State::Value::None;
state = State::Value(state | State::MoveUp);
if (mState & State::MoveUp) {
movement.y -= mPlayerSpeed;
}
about overloading:
inline State::Value& operator|=(State::Value& a, State::Value b) {
return a = static_cast<State::Value> (a | b);
}
and since you use C++11, you should use constexpr every were is possible:
inline constexpr State::Value operator|(State::Value a, State::Value b) {
return a = static_cast<State::Value> (a | b);
}
inline constexpr State::Value operator&(State::Value a, State::Value b) {
return a = static_cast<State::Value> (a & b);
}

To be honest I don't think there is a consistent pattern for them.
Just look at std::ios_base::openmode and std::regex_constants::syntax_option_type as two completely different ways of structuring it in the standard library -- one using a struct, the other using an entire namespace. Both are enums all right, but structured differently.
Check your standard library implementation to see the details of how the above two are implemented.

Related

How to safely compare two unsigned integer counters?

We have two unsigned counters, and we need to compare them to check for some error conditions:
uint32_t a, b;
// a increased in some conditions
// b increased in some conditions
if (a/2 > b) {
perror("Error happened!");
return -1;
}
The problem is that a and b will overflow some day. If a overflowed, it's still OK. But if b overflowed, it would be a false alarm. How to make this check bulletproof?
I know making a and b uint64_t would delay this false-alarm. but it still could not completely fix this issue.
===============
Let me clarify a little bit: the counters are used to tracking memory allocations, and this problem is found in dmalloc/chunk.c:
#if LOG_PNT_SEEN_COUNT
/*
* We divide by 2 here because realloc which returns the same
* pointer will seen_c += 2. However, it will never be more than
* twice the iteration value. We divide by two to not overflow
* iter_c * 2.
*/
if (slot_p->sa_seen_c / 2 > _dmalloc_iter_c) {
dmalloc_errno = ERROR_SLOT_CORRUPT;
return 0;
}
#endif
I think you misinterpreted the comment in the code:
We divide by two to not overflow iter_c * 2.
No matter where the values are coming from, it is safe to write a/2 but it is not safe to write a*2. Whatever unsigned type you are using, you can always divide a number by two while multiplying may result in overflow.
If the condition would be written like this:
if (slot_p->sa_seen_c > _dmalloc_iter_c * 2) {
then roughly half of the input would cause a wrong condition. That being said, if you worry about counters overflowing, you could wrap them in a class:
class check {
unsigned a = 0;
unsigned b = 0;
bool odd = true;
void normalize() {
auto m = std::min(a,b);
a -= m;
b -= m;
}
public:
void incr_a(){
if (odd) ++a;
odd = !odd;
normalize();
}
void incr_b(){
++b;
normalize();
}
bool check() const { return a > b;}
}
Note that to avoid the overflow completely you have to take additional measures, but if a and b are increased more or less the same amount this might be fine already.
The posted code actually doesn’t seem to use counters that may wrap around.
What the comment in the code is saying is that it is safer to compare a/2 > b instead of a > 2*b because the latter could potentially overflow while the former cannot. This particularly true of the type of a is larger than the type of b.
Note overflows as they occur.
uint32_t a, b;
bool aof = false;
bool bof = false;
if (condition_to_increase_a()) {
a++;
aof = a == 0;
}
if (condition_to_increase_b()) {
b++;
bof = b == 0;
}
if (!bof && a/2 + aof*0x80000000 > b) {
perror("Error happened!");
return -1;
}
Each a, b interdependently have 232 + 1 different states reflecting value and conditional increment. Somehow, more than an uint32_t of information is needed. Could use uint64_t, variant code paths or an auxiliary variable like the bool here.
Normalize the values as soon as they wrap by forcing them both to wrap at the same time. Maintain the difference between the two when they wrap.
Try something like this;
uint32_t a, b;
// a increased in some conditions
// b increased in some conditions
if (a or b is at the maximum value) {
if (a > b)
{
a = a-b; b = 0;
}
else
{
b = b-a; a = 0;
}
}
if (a/2 > b) {
perror("Error happened!");
return -1;
}
If even using 64 bits is not enough, then you need to code your own "var increase" method, instead of overload the ++ operator (which may mess your code if you are not careful).
The method would just reset var to '0' or other some meaningfull value.
If your intention is to ensure that action x happens no more than twice as often as action y, I would suggest doing something like:
uint32_t x_count = 0;
uint32_t scaled_y_count = 0;
void action_x(void)
{
if ((uint32_t)(scaled_y_count - x_count) > 0xFFFF0000u)
fault();
x_count++;
}
void action_y(void)
{
if ((uint32_t)(scaled_y_count - x_count) < 0xFFFF0000u)
scaled_y_count+=2;
}
In many cases, it may be desirable to reduce the constants in the comparison used when incrementing scaled_y_count so as to limit how many action_y operations can be "stored up". The above, however, should work precisely in cases where the operations remain anywhere close to balanced in a 2:1 ratio, even if the number of operations exceeds the range of uint32_t.

use typedef for more type safe in c++

I would like to revisit the post. Currently, I am trying to avoid bug created by mixing Rad and Degree types for angles in my program.
For example:
typedef float Degree;
typedef float Radian;
Degree a = 15.;
Radian b = 3.14/4.;
float c = a + b; // no compile error
is there new update solution for this?
EDIT 01:
I resort to write my own class with hope for its small size and no dependency. Here's the working code
#include <stdio.h>
#include <iostream>
template<typename numT>
class RadAngle {
public:
RadAngle() {
AngVal = 0.0;
}
RadAngle(const numT& angV) {
AngVal = angV;
}
void operator = (const RadAngle<numT>& ang1) {
AngVal = ang1.getVal();
}
RadAngle operator+(const RadAngle<numT>& ang1) const { return RadAngle<numT>(AngVal+ang1.getVal()); }
RadAngle operator-(const RadAngle<numT>& ang1) const { return RadAngle<numT>(AngVal-ang1.getVal()); }
RadAngle operator*(const RadAngle<numT>& ang1) const { return RadAngle<numT>(AngVal*ang1.getVal()); }
RadAngle operator/(const RadAngle<numT>& ang1) const { return RadAngle<numT>(AngVal/ang1.getVal()); }
numT getVal() const { return AngVal;};
private:
numT AngVal;
};
int main() {
RadAngle<float> a(1.5);
RadAngle<float> b(3.14);
RadAngle<float> c = a+b;
//std::cout << c << std::endl;
// printf("%.2f",c.getVal());
return 0;
}
What you have doesn't help type safety at all, except perhaps as weak documentation. As far as the compiler is concerned, float, Degree, and Radian are complete synonyms; this is called a weak type alias. Strong type aliases are not a part of C++, but you can work around that. Two good articles on that are here and here. The basic idea is to create a generic class template for a strong typedef, and use that to create each individual alias.
If you don't want to write all the boilerplate yourself even once, I recommend using a third-party library to handle this. Both the authors of the posts I linked above wrote libraries for it, NamedType and type_safe. If you need something heavier-duty, you should check out Boost.Units. Note that I haven't used any of these myself; they're just where I'd check if I needed those features.
You didn't ask about this, but none of this should have any runtime performance costs over just using float everywhere and keeping track of units manually, but might make compilation slower.
Your best bet is to create a class for each kind of measurement and implement ways to convert one to another. The classes could/should have a common superclass.
I would pick one as internal representation (e.g. Radian) and write other as wrapper classes
typedef double Radian;
class Degree {
public:
Degree() {
m_radian = 0.0;
}
Degree(double degree) {
m_radian = degree / 180.0 * 3.1415926;
}
void operator = (double degree) {
m_radian = degree / 180.0 * 3.1415926;
}
operator Radian() const { return m_radian; }
private:
Radian m_radian;
};
void print_rad(Radian rad) {
printf("rad: %lf\n", rad);
}
int main() {
Radian rad = 123.0;
Degree degree = 456.0;
print_rad(rad);
print_rad(degree);
print_rad(rad + degree);
return 0;
}
Output:
rad: 123.000000
rad: 7.958701
rad: 130.958701
Well, you probably want to go the whole way with calculating with units.
Do something like this, with all relevant (SI?) base-units:
template <class T, int meter, int second, int pow_10, int pow_deginrad>
class unit {
T num = 0;
};
// add convenience typedefs. Also look into `operator ""` for denoting literals.
Now you only have to define arithmetic between the types and magnitudes in one place.
Happy coding.
Your approach is a bit flawed, I think.
What you trying to model are physical quantities - types that have a value and a unit.
There is no quantity called a radian. There is a quantity called angle whose units may be radians or degrees.
What you need to is a bit of infrastructure to deal with converting units of quantities and performing operations on units as well as the values.
For example,
L1 = 10 "m" (length)
L2 = 20 "m" (length)
L1 * L2 = 200 "m^2" (area)
F1 = 10 "N" (force)
A1 = 2 "m^2" (area)
F1/A1 = 5 "Pa" (pressure)
A2 = 10 "deg"
convert(A2, "rad") = 0.174533 "rad"
If you are able to add the code for dealing with units, rest of the functionality will be easy.
We have had to do that at my work and the amount of code is non-trivial. It does not make sense for me delver further into that subject here.
Potential C++ code:
struct Quantity
{
double value;
std::string unit;
};
// Defines operations on Quantity.
Quantity operator+(Quantity const& q1, Quantity const& q2) { ... }
Quantity operator-(Quantity const& q1, Quantity const& q2) { ... }
Quantity operator*(Quantity const& q1, Quantity const& q2) { ... }
Quantity operator*(Quantity const& q1, double f) { ... }
Quantity operator/(Quantity const& q1, Quantity const& q2) { ... }
Quantity operator/(Quantity const& q1, double f) { ... }
Quantity convert(Quantity const& q, std::string const& unit) { ... }
auto L1 = Quantity(10, "m");
auto L2 = Quantity(10, "m");
auto a = L1*L2; // Resulting in Quantity(100, "m^2")
auto F1 = Quantity(10, "N");
auto A1 = Quantity(2, "m^2");
auto p = F1/A1; // Resulting in Quantity(5, "Pa")
auto A2 = Quantity(10, "deg");
auto A3 = Convert(A2, "rad"); // Resulting in Quantity(0.174533, "rad")

Is there a concise opposite of "empty"?

Interfaces to string classes typically have of method named IsEmpty (VCL) or empty (STL). That's absolutely reasonable because it's a special case, but the code that uses these methods often has to negate this predicate, which leads to a "optical (and even psychological) overhead" (the exclamation mark is not very obvious, especially after an opening parenthesis). See for instance this (simplified) code:
/// format an optional time specification for output
std::string fmtTime(const std::string& start, const std::string& end)
{
std::string time;
if (!start.empty() || !end.empty()) {
if (!start.empty() && !end.empty()) {
time = "from "+start+" to "+end;
} else {
if (end.empty()) {
time = "since "+start;
} else {
time = "until "+end;
}
}
}
return time;
}
It has four negations, because the empty cases are those to be skipped. I often observe this kind of negation, also when designing interfaces, and it's not a big problem but it's annoying. I only wish to support writing understandable and easy-to-read code. I hope you'll understand my point.
Maybe I'm only struck with blindness: How would you solve the above problem?
Edit: After reading some comments, I think it's nessessary to say that the original code uses the class System::AnsiString of the VCL. This class provides an IsEmpty method, which is very readable:
if (text.IsEmpty()) { /* ... */ } // read: if text is empty ...
if not negated:
if (!text.IsEmpty()) { /* ... */} // read: if not text is empty ...
...instead of if text is not empty. I think the literal is was better left to the reader's fantasy to let also the negation work well. Ok, maybe not a widespread problem...
In most cases you can reverse the order of the ifand the else to clean up the code:
const std::string fmtTime(const std::string& start, const std::string& end)
{
std::string time;
if (start.empty() && end.empty()) {
return time;
}
if (start.empty() || end.empty()) {
if (end.empty()) {
time = "since "+start;
} else {
time = "until "+end;
}
} else {
time = "from "+start+" to "+end;
}
return time;
}
Or even cleaner after some more refactoring:
std::string fmtTime(const std::string& start, const std::string& end)
{
if (start.empty() && end.empty()) {
return std::string();
}
if (start.empty()) {
return "until "+end;
}
if (end.empty()) {
return "since "+start;
}
return "from "+start+" to "+end;
}
And for the ultimate compactness (although I prefer the previous version, for its readability):
std::string fmtTime(const std::string& start, const std::string& end)
{
return start.empty() && end.empty() ? std::string()
: start.empty() ? "until "+end
: end.empty() ? "since "+start
: "from "+start+" to "+end;
}
Another possibility is to create a helper function:
inline bool non_empty(const std::string &str) {
return !str.empty();
}
if (non_empty(start) || non_empty(end)) {
...
}
I think I'd eliminate the conditions in favor of a little math:
const std::string fmtTime(const std::string& start, const std::string& end) {
typedef std::string const &s;
static const std::function<std::string(s, s)> f[] = {
[](s a, s b) { return "from " + a + " to " + b; }
[](s a, s b) { return "since " + a; },
[](s a, s b) { return "until " + b; },
[](s a, s b) { return ""; },
};
return f[start.empty() * 2 + end.empty()](start, end);
}
Edit: if you prefer, you can express the math as start.empty() * 2 + end.empty(). To understand what's going on, perhaps it's best if I expound on how I thought of things to start with. I thought of things as a 2D array:
(Feel free to swap the "start empty" and "end empty", depending on whether you prefer to think in row-major or column-major order).
The start.empty() and end.empty() (or the logical not of them, if you prefer) each act as as an index along one dimension of this 2D matrix. The math involved simply "linearizes" that addressing, so instead of two rows and two columns, we get one long row, something like this:
In mathematical terms, that's a simple matter of "row * columns + column" (or, again, vice versa, depending on whether you prefer row-major or column-major ordering). I originally expressed the * 2 part as a bit-shift and the addition as a bit-wise or (knowing the least significant bit is empty, because of the previous left-shift). I find that easy to deal with, but I guess I can understand where others might not.
I should probably add: although I've already mentioned row-major vs. column-major, it should be fairly obvious that the mapping from the two "x.empty" values to positions in the array is basically arbitrary. The value we get from .empty() means that we get a 0 when the value is not present, and a 1 when it is. As such, a direct mapping from the original values to the array positions is probably like this:
Since we're linearizing the value we have a few choices for how we do the mapping:
simply arrange the array to suit the values as we get them.
invert the value for each dimension individually (this is basically what led to the original question--the constant use of !x.empty())
Combine the two inputs into a single linear address, then "invert" by subtracting from 3.
For those who doubt the efficiency of this, it actually compiles down to this (with VC++):
mov eax, ebx
cmp QWORD PTR [rsi+16], rax
sete al
cmp QWORD PTR [rdi+16], 0
sete bl
lea eax, DWORD PTR [rbx+rax*2]
movsxd rcx, eax
shl rcx, 5
add rcx, r14
mov r9, rdi
mov r8, rsi
mov rdx, rbp
call <ridiculously long name>::operator()
Even the one-time construction for f isn't nearly as bad as some might think. It doesn't involve dynamic allocation, or anything on that order. The names are long enough that it looks a little scary initially, but in the end, it's mostly four repetitions of:
lea rax, OFFSET FLAT:??_7?$_Func_impl#U?$_Callable_obj#V<lambda_f466b26476f0b59760fb8bb0cc43dfaf>##$0A##std##V?$allocator#V?$_Func_class#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##AEBV12#AEBV12##std###2#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##2#AEBV42#AEBV42##std##6B#
mov QWORD PTR f$[rsp], rax
Leaving out the static const doesn't really seem to affect execution speed much. Since the table is static, I think it should be there, but as far as execution speed goes, it's not the kind of massive win we might expect if the table initialization involved four separate dynamic allocations, or anything like that.
You could say
if (theString.size()) { .... }
Whether that is more readable is a different matter. Here you are calling a method whose primary purpose is not to tell you if the thing is empty, and relying on an implicit conversion to bool. I would prefer the !s.empty() version. I might use not instead for fun:
if (not theString.empty()) { .... }
It might be interesting to see the correlation between people who find the ! and not versions confusing.
I have to refactor this, purely out of anal retentive disorder…
std::string fmtTime( const std::string & start, const std::string & end ) {
if ( start.empty() ) {
if ( end.empty() ) return ""; // should diagnose an error here?
return "until " + end;
}
if ( end.empty() ) return "since " + start;
return "from " + start + " to " + end;
}
There… clean clean clean. If something here is difficult to read, add a comment, not another if clause.
Usually it's just better to not use such complicated conditional code. Why not keep it simple?
const std::string fmtTime(const std::string& start, const std::string& end)
{
if (start.empty() && end.empty())
{
return "";
}
// either start or end or both are not empty here.
std::string time;
if (start.empty())
{
time = "until "+end;
}
else if (end.empty())
{
time = "since "+start;
}
else // both are not empty
{
time = "from "+start+" to "+end;
}
return time;
}
Globally, I have no problem with the way you've written it; it's
certainly cleaner that the alternatives that others are
proposing. If you're worried about the ! disappearing (which
is a legitimate worry), use more white space.
if ( ! start.empty() || ! end.empty() ) ...
Or try using the keyword not instead:
if ( not start.empty() || not end.empty() ) ...
(With most editors, the not will be highlighted as a keyword,
which will draw even more attention to it.)
Otherwise, two helper functions:
template <typename Container>
bool
isEmpty( Container const& container )
{
return container.empty();
}
template <typename Container>
bool
isNotEmpty( Container const& container )
{
return !container.empty();
}
This has the added advantage of giving the functionality
a better name. (Function names are verbs, so c.empty()
logically means "empty the container", and not "is the container
empty". But if you start wrapping all of the functions in the
standard library that have poor names, you've got your work cut
out for you.)
Without using negation.. ;)
const std::string fmtTime(const std::string& start, const std::string& end)
{
std::string ret;
if (start.empty() == end.empty())
{
ret = (start.empty()) ? "" : "from "+start+" to "+end;
}
else
{
ret = (start.empty()) ? "until "+end : "since "+start;
}
return ret;
}
EDIT: okay cleaned up a little more...
Since no one cared to type the complete answer with my comment, here it goes:
Create local variables that simplify the reading of expressions:
std::string fmtTime(const std::string& start, const std::string& end)
{
std::string time;
const bool hasStart = !start.empty();
const bool hasEnd = !end.empty();
if (hasStart || hasEnd) {
if (hasStart && hasEnd) {
time = "from "+start+" to "+end;
} else {
if (hasStart) {
time = "since "+start;
} else {
time = "until "+end;
}
}
}
return time;
}
The compiler is smart enough to elide those variables, and even if it did not, it won't be less efficient than the original (I expect both to be a single test of a variable). The code now is a bit more readable for a human that can just read the conditions:
if has start or end then
Of course you might also do different refactors to further simplify the number of nested operations, like singling out when there is no start or end and bailing out early...
I struggle with the psychological overhead of negative logic as well.
One solution to this (when it cannot be avoided) is to check for the explicit condition, consider:
if (!container.empty())
vs
if (container.empty() == false)
The second version is easier to read because it flows as you would read it out loud. It also makes it clear that you're checking a false condition.
Now if that is still not good enough for you, my advice would be to create a thin wrapper class that inherits from whatever container you're using and then create your own method for that particular check.
For example with strings:
class MyString : public std::string
{
public:
bool NotEmpty(void)
{
return (empty() == false);
}
};
Now it becomes just:
if (container.NotEmpty())...
If all you're concerned about is the ease with which ! can be overlooked, you can use the standard C++ alternative token not instead:
const std::string fmtTime(const std::string& start, const std::string& end)
{
std::string time;
if (not start.empty() or not end.empty()) {
if (not start.empty() and not end.empty()) {
time = "from "+start+" to "+end;
} else {
if (end.empty()) {
time = "since "+start;
} else {
time = "until "+end;
}
}
}
return time;
}
(Refer to [lex.digraph] in the standard for alternative tokens)
Would you consider assigned a good opposite?
#include <string>
template <typename CharType>
bool assigned(const std::basic_string<CharType>& s)
{
return !s.empty();
}
std::string fmtTimeSpec(const std::string& from, const std::string& to)
{
if (assigned(from)) {
if (assigned(to)) {
return "from "+from+" to "+to;
}
return "since "+from;
}
if (assigned(to)) {
return "until "+to;
}
return std::string();
}
Structural improvements of the "test function" came from numerous useful answers. Special thanks to:
C. E. Gesser
Potatoswatter
To express the opposite form of ".isEmpty()" usage, I prefer this way:
if (textView.getText().toString().isEmpty()){
//do the thing if textView has nothing inside as typed.
}else if (textView.getText().toString() != ""){
// do the thing if textView has something inside as typed.
}
Also, you may use ".equals("")" instead of "!=" typography as recommended by Android Studio.
textView.getText().toString().equals("")
Coming back to the API design aspect
(it may not be applicable to strings, but on container classes in general)
By pure chance I found an excellent answer to this old question (emphasizes mine)
What about using any()? [...]
in a completely unrelated post being the answer to the question
How do I know if a generator is empty from the start?
To contrast empty and any might be poor in English but it absolutely makes sense in API design.
A better way to express options
To be quite honest: Until now, I didn't even realize that I misused string type to negatively(!) express the presence of boundaries of a range. And that was obviously the real cause of my headache.
C++17 introduced optional. So there is little reason left to complain about the shortcomings (in terms of expressiveness) of empty() and negation.
Let's have a look at a working example,[1] [2] that uses the original string type and – as a proof of concept – another type (int for simplicity, this should better be some date type):
#include <iostream>
#include <optional>
#include <string>
#include <sstream>
template <typename T>
std::string format_range(const std::optional<T>& start,
const std::optional<T>& end)
{
std::stringstream range;
if (start) {
if (end) {
range << "from " << *start << " to " << *end;
} else {
range << "since " << *start;
}
} else if (end) {
range << "until " << *end;
}
return range.str();
}
template <typename T>
void invoke_format_range(const T& start, const T& end)
{
using namespace std;
optional<T> NONE;
cout << format_range<T>(NONE, NONE) << endl;
cout << format_range<T>(start, NONE) << endl;
cout << format_range<T>(NONE, end) << endl;
cout << format_range<T>(start, end) << endl;
}
int main()
{
invoke_format_range(std::string("START"), std::string("END"));
invoke_format_range(1, 12);
return 0;
}
[1]
If you cannot use a C++17 compatible compiler, it is relatively easy to adapt optional using your own rudimentary implementation (or try boost::optional of course).
[2]
See online demo at https://onlinegdb.com/OCw2c5mkO

XOR operator not evaluating correctly in C++

I'm building a BigInt class from scratch in C++, but something is driving me nuts: my XOR isn't working properly, and I have no idea why. I was hoping someone could enlighten me. Below is a minimal working example:
class BigInt
{
private:
bool pos;
int size; // Number of binary digits to use
short compare(BigInt input);
public:
BigInt(long long input, int inSize) { pos = true; size = inSize; }
};
short BigInt::compare(BigInt input)
{
// Partial compare function for minimal working example
// Return:
// 1: (*this) > input
// 0: (*this) == input
// -1: (*this) < input
string a = (*this).toDecimal(), b = input.toDecimal();
bool c = (*this).size > input.size, d = (*this).pos ^ input.pos;
bool thispos = (*this).pos, inpos = input.pos;
bool xorpos = (thispos != inpos);
bool x = true, y = true;
bool z = x ^ y;
if ((*this).size > input.size || (*this).pos != input.pos)
return 1 - ((*this).pos ? 0 : 2);
else if ((*this).size < input.size)
return -1 + ((*this).pos ? 0 : 2);
return 0;
}
I have a breakpoint on the first if statement. Below is what I have on my watch list.
thispos true bool
inpos true bool
xorpos true bool
x true bool
y true bool
z false bool
Anyone know what's going on? I'd rather avoid kluging my if statement. I've never had a problem with such simple usage of my XOR.
As far as I can tell, there should be nothing wrong, but there's something about these values that just won't evaluate the way they're expected to.
Edit: Changed code to minimal working example.
Well, even though ^ is a bitwise xor operator, your initializations
bool thispos = (*this).pos, inpos = input.pos;
are required to convert the source values to bool type. Values of bool type are guaranteed to act as either 0 or 1 in arithmetic contexts. This means that
bool xorpos = thispos ^ inpos;
is required to initialize xorpos with false if both thispos and inpos were originally true.
If you observe different behavior, it might be a bug in your compiler. Integral-to-bool conversion might be implemented incorrectly or something like that.
Another opportunity is that someone "redefined" the bool keyword by doing something like
#define bool unsigned char
This will disable the proper bool semantics in the first pair of initializations and cause the bitwise nature of ^ to affect the result.
Why not simply do x != y? This is more consistent with your types as well.

how to improve natural sort program for decimals?

I have std::strings containing numbers in the leading section that I need to sort. The numbers can be integers or floats.
The vector<std::string> sort was not optimal, I found the following natural sort program which was much better. I still have a small issue with numbers smaller than zero that do not sort just right. Does anyone have a suggestion to improve? We're using Visual Studio 2003.
The complete program follows.
TIA,
Bert
#include <list>
#include <string>
#include <iostream>
using namespace std;
class MyData
{
public:
string m_str;
MyData(string str) {
m_str = str;
}
long field1() const
{
int second = m_str.find_last_of("-");
int first = m_str.find_last_of("-", second-1);
return atol(m_str.substr(first+1, second-first-1).c_str());
}
long field2() const
{
return atol(m_str.substr(m_str.find_last_of("-")+1).c_str());
}
bool operator < (const MyData& rhs)
{
if (field1() < rhs.field1()) {
return true;
} else if (field1() > rhs.field1()) {
return false;
} else {
return field2() < rhs.field2();
}
}
};
int main()
{
// Create list
list<MyData> mylist;
mylist.push_front(MyData("93.33"));
mylist.push_front(MyData("0.18"));
mylist.push_front(MyData("485"));
mylist.push_front(MyData("7601"));
mylist.push_front(MyData("1001"));
mylist.push_front(MyData("0.26"));
mylist.push_front(MyData("0.26"));
// Sort the list
mylist.sort();
// Dump the list to check the result
for (list<MyData>::const_iterator elem = mylist.begin(); elem != mylist.end(); ++elem)
{
cout << (*elem).m_str << endl;
}
return 1;
}
GOT:
0.26
0.26
0.18
93.33
485
1001
7601
EXPECTED:
0.18
0.26
0.26
93.33
485
1001
7601
Use atof() instead of atol() to have the comparison take the fractional part of the number into account. You will also need to change the return types to doubles.
If it's just float strings, I'd rather suggest to create a table with two columns (first row contains the original string, second row is filled with the string converted to float), sort this by the float column and then output/use the sorted string column.
If the data are all numbers I would create a new class to contain the data.
It can have a string to include the data but then allows you to have better methods to model behaviour - in this case espacially to implement operator <
The implementation could also include use of a library that calculates to exact precion e.g. GNU multiple precision this would do the comparison and canversion from string (or if the numbers do not have that many significant figures you could use doubles)
I would compute the values once and store them.
Because they are not actually part of the objects state (they are just calcualted values) mark them as mutable. Then they can also be set during const methods.
Also note that MyClass is a friend of itself and thus can access the private members of another object of the same class. So there is no need for the extranious accessor methods. Remember Accessor methods are to protect other classes from changes in the implementation not the class you are implementing.
The problem with ordering is that atoi() is only reading the integer (ie it stops at the '.' character. Thus all your numbers smaller than 0 have a zero value for comparison and thus they will appear in a random order. To compare against the full value you need to extract them as a floating point value (double).
class MyData
{
private:
mutable bool gotPos;
mutable double f1;
mutable double f2;
public:
/*
* Why is this public?
*/
std::string m_str;
MyData(std::string str)
:gotPos(false)
,m_str(str) // Use initializer list
{
// If you are always going to build f1,f2 then call BuildPos()
// here and then you don't need the test in the operator <
}
bool operator < (const MyData& rhs)
{
if (!gotPos)
{ buildPos();
}
if (!rhs.gotPos)
{ rhs.buildPos();
}
if (f1 < rhs.f1) return true;
if (f1 > rhs.f1) return false;
return f2 < rhs.f2;
}
private:
void buildPos() const
{
int second = m_str.find_last_of("-");
int first = m_str.find_last_of("-", second-1);
// Use boost lexical cast as it handles doubles
// As well as integers.
f1 = boost::lexical_cast<double>(m_str.substr(first + 1, second-first - 1));
f2 = boost::lexical_cast<double>(m_str.substr(second + 1));
gotPos = true;
}
};