Appending a number to enum to get other enum - c++

I want to get the enum value in a for loop, by appending a number, like
enum example
{
Example_1,
Example_2,
Example_3,
.
.
.
Example_n
};
example x;
for (i = 0; i < n; i++
{x = Example_ + i; // if i = 5, I need Example_5
}
I want this implementation in C++11

If you have an Example_0 in the enum, then Example_0 + 5 will give you an integer value equivalent to Example_5. Enums are just integers.
All this assuming that you don't explicitly assign a value to a certain enumeration constant - that's another story.

You cannot concatenate name with number to retrieve enum name and use enum value.
With contiguous enum, you can use simple arithmetic.
you can create operator++ for your enum, resolve by switch:
example operator++(example e)
{
switch (e) {
case Example_1: return Example_2;
case Example_2: return Example_3;
case Example_3: return Example_4;
// ...
case Example_n: return Last;
};
throw std::runtime("value out of range");
}
and so, possibly
for (example e = Example_1: e != Last; ++e) {/*..*/}
using array to provide enum list:
constexpr auto AllExamples() {
constexpr std::array res{{Example_1,
Example_2,
/*..*/,
Example_n}};
return res;
}
which allows:
for (auto ex : AllExamples()) {/*..*/}
f(AllExamples()[5]);
or use map if you really have to play with names:
std::map<std::string, example> ExamplesAsMap() {
return {
{"Example_1", Example_1},
{"Example_2", Example_2},
/*..*/
{"Example_n", Example_n},
{"Value_1", Value_1},
{"Value_2", Value_2},
/*..*/
{"Value_n", Value_n}
/**/
};
}
And then
const auto m = ExamplesAsMap();
example x;
for (int i = 0; i < n; i++) {
x = m.at("Example_" + std::to_string(i));
// ...
}

Related

Comparing string* in C++

Let a and b be given positive integers . Consider the following C++17 code :
string* first;
first = new string[a];
//some definitions
string* second;
second = new string[b];
//some definitions
By saying a string first[i] is undefined, I mean no definition is ever made to the string first[i] after the creation code given above.
I define first and second to be equal if:
a==b.
first[i] and second[i] are equivalent for every non-negative integer i<a, in the following sense: if first[i] is undefined, then so is second[i]; if first[i] has length l (where l is a non-negative integer), then second[i] has length l and first[i][j] is the same char as second[i][j] for every non-negative integer j<l.
In short, I want the most ordinary string equality with the emphasis on comparing the contents rather than the pointers. What is the most appropriate way to do this in C++17? I tried multiple answers and none of them works.
I'm assuming string is std::string.
The real solution here would be to use std::vector<std::string> rather than managing your own dynamic memory:
std::vector<std::string> first;
//some definitions
std::vector<std::string> second;
//some definitions
bool equal = (first == second); // does what you want
If, for some reason, you cannot use std::vector, the C-style approach would look something like
bool are_equal(std::string* first, std::size_t first_size, std::string* second, std::size_t second_size) {
if (first_size != second_size) return false;
for (std::size_t idx = 0; idx != first_size; ++idx) {
if (first[idx] != second[idx]) return false;
}
return true;
}
int main() {
string* first = new string[a];
//some definitions
string* second = new string[b];
//some definitions
bool equal = are_equal(first, a, second, b);
return 0;
}
With C++20, prefer using std::span here
bool are_equal(std::span<const std::string> first, std::span<const std::string> second) {
if (first.size() != second.size()) return false;
for (std::size_t idx = 0; idx != first.size(); ++idx) {
if (first[idx] != second[idx]) return false;
}
return true;
}
int main() {
string* first = new string[a];
//some definitions
string* second = new string[b];
//some definitions
bool equal = are_equal({first, a}, {second, b});
return 0;
}

Static array size determined from template values

I'm trying to use static array which size needs to be determined by given template values. However size will be constant across program runtime - thats why I decided not to use std::vector.
template<uint32_t BAR_WIDTH>
class Bar
{
//do_stuff...
Foo mapper[ [&]()->int{ uint32_t tmp = BAR_WIDTH / Foo:FOO_EDGE; return (BAR_WIDTH % 10 == 0) ? tmp : tmp + 1; }; ];
};
FOO_EGDE is const static value. IDE gives me a hint that
Array size expression must have an integer type instead of int(*)()
I wonder if I can make it work this way without using std::vector. Any advice is welcomed and appreciated.
The problem is, that you are using a lambda for determining the size of the array. If you leave it off and just use the ternary operator, it works:
int main() {
const bool z = true;
const int x = 5, y = 3;
int arr[z ? x : y];
return 0;
}
Ideone
As opposed to:
int main() {
const bool z = true;
const int x = 5, y = 3;
int arr[[&]() -> int { return z ? x : y; }];
return 0;
}
Ideone
As described here, lambda expressions can't be constexpr yet, and you can only declare the size of an array with a constexpr value (even then, you are not trying to invoke declared lambda (to invoke it - () is required at the end of declaration).
To work around such problem, you could use a private static constexpr method, and use the return value of it, for the array size declaration:
static constexpr uint32_t GetArraySize ()
{
uint32_t tmp = BAR_WIDTH / Foo::FOO_EDGE;
return (BAR_WIDTH % 10 == 0) ? tmp : tmp + 1;
}
Foo mapper[GetArraySize ()];

Condensing a do-while loop to a #define macro

Consider the following sample code (I actually work with longer binary strings but this is enough to explain the problem):
void enumerateAllSubsets(unsigned char d) {
unsigned char n = 0;
do {
cout<<binaryPrint(n)<<",";
} while ( n = (n - d) & d );
}
The function (due to Knuth) effectively loops through all subsets of a binary string;
For example :
33 = '00100001' in binary and enumerateAllSubsets(33) would produce:
00000000, 00100000, 00000001, 00100001.
I need to write a #define which would make
macroEnumerate(n,33)
cout<<binaryPrint(n)<<",";
behave in a way equivalent to enumerateAllSubsets(33). (well, the order might be rearranged)
Basically i need the ability to perform various operations on subsets of a set.
Doing something similar with for-loops is trivial:
for(int i=0;i < a.size();i++)
foo(a[i]);
can be replaced with:
#define foreach(index,container) for(int index=0;index < container.size();index++)
...
foreach(i,a)
foo(a[i]);
The problem with enumerateAllSubsets() is that the loop body needs to be executed once unconditionally and as a result the do-while cannot be rewritten as for.
I know that the problem can be solved by STL-style templated function and a lambda passed to it (similar to STL for_each function), but some badass #define macro seems like a cleaner solution.
Assuming C++11, define a range object:
#include <iostream>
#include <iterator>
#include <cstdlib>
template <typename T>
class Subsets {
public:
Subsets(T d, T n = 0) : d_(d), n_(n) { }
Subsets begin() const { return *this; }
Subsets end() const { return {0, 0}; }
bool operator!=(Subsets const & i) const { return d_ != i.d_ || n_ != i.n_; }
Subsets & operator++() {
if (!(n_ = (n_ - d_) & d_)) d_ = 0;
return *this;
}
T operator*() const { return n_; }
private:
T d_, n_;
};
template <typename T>
inline Subsets<T> make_subsets(T t) { return Subsets<T>(t); }
int main(int /*argc*/, char * argv[]) {
int d = atoi(argv[1]);
for (auto i : make_subsets(d))
std::cout << i << "\n";
}
I've made it quite general in case you want to work with, e.g., uint64_t.
One option would be to use a for loop that always runs at least once, such as this:
for (bool once = true; once? (once = false, true) : (n = (n - d) & d); )
// loop body
On the first iteration, the once variable gets cleared and the expression evaluates to true, so the loop executes. From that point forward, the actual test-and-step logic controls the loop.
From here, rewriting this to a macro should be a lot easier.
Hope this helps!
You can do a multiline macro that uses an expression, like this:
#define macroenum(n, d, expr ) \
n = 0; \
do { \
(expr); \
} while (n = (n -d) & d) \
; \
int main(int argc, const char* argv[])
{
enumerateAllSubsets(33);
int n;
macroenum(n, 33, cout << n << ",");
}
As others have mentioned this will not be considered very clean by many - amongst other things, it relies on the variable 'n' existing in scope. You may need to wrap expr in another set of parens, but I tested it with g++ and got the same output as enumerateAllSubsets.
It seems like your goal is to be able to do something like enumerateAllSubsets but change the action performed for each iteration.
In C++ you can do this with a function in the header file:
template<typename Func>
inline void enumerateAllSubsets(unsigned char d, Func f)
{
unsigned char n = 0;
do { f(n); } while ( n = (n - d) & d );
}
Sample usage:
enumerateAllSubsets(33, [](auto n) { cout << binaryPrint(n) << ','; } );

How can I return an array?

Is there any way to return an array from a function? More specifically, I've created this function:
char bin[8];
for(int i = 7; i >= 0; i--)
{
int ascii='a';
if(2^i-ascii >= 0)
{
bin[i]='1';
ascii=2^i-ascii;
}
else
{
bin[i]='0';
}
}
and I need a way to return bin[].
You can't do that but you can:
return a dynamicaly allocated array - best owned by a smart pointer so that the caller does not have to care about deallocating memory for it - you could also return something like an std::vector this way.
populate an array/vector passed to you as an argument by pointer (suggested) or a non const reference.
Your array is a local variable allocated on the stack. You should use new [] to allocate it on the heap. Then you can just say: return bin;. Beware that you will have to explicitly free it with delete [] when you are done with it.
You are really asking the wrong question. If you want to do string processing in C++, use the std::string and/or std::vector classes, not arrays of char. Your code then becomes:
vector <char> func() {
vector <char> bin(8);
for( int i = 7; i >= 0; i-- ) {
int ascii='a';
if ( 2 ^ i - ascii >= 0 ) {
bin[i] = '1';
ascii = 2^i - ascii;
}
else {
bin[i] ='0';
}
}
return bin;
}
I think your best bet is to use a vector. It can function in many ways like an array and has several upsides (length stored with type, automatic memory management).
void Calculate( std::vector<char>& bin) {
for(int i = 7; i >= 0; i--)
{
int ascii='a';
if(2^i-ascii >= 0)
{
bin.push_back('1');
ascii=2^i-ascii;
}
else
{
bin.push_back('0');
}
}
}
If you want to return a copy of the array (might make sense for small arrays) and the array has fixed size, you can enclose it in a struct;
struct ArrayWrapper {
char _bin[8];
};
ArrayWrapper func()
{
ArrayWrapper x;
// Do your stuff here using x._bin instead of plain bin
return x;
}
Or just use a std::vector as has been already suggested.
Similar implemented to #ari's answer, i want to say there is already a boost solution, boost::array solving your problem:
boost::array<char, 8> f() {
boost::array<char, 8> bin;
for(int i = 7; i >= 0; i--) {
int ascii = 'a';
if(2 ^ i-ascii >= 0) {
bin[i] = '1';
ascii = 2 ^ i-ascii;
} else {
bin[i] = '0';
}
}
}
...
boost::array<char, 8> a(f());
[I'm not sure what you want to do with that algorithm though, but note that i think you want to do 1 << i (bit-wise shift) instead of 2 ^ i which is not exponentiation in C++.]
Boost array is a normal array, just wrapped in a struct, so you lose no performance what-so-ever. It will also be available in the next C++ version as std::array, and is very easy to do yourself if you don't need the begin()/size()/data()-sugar it adds (to be a container). Just go with the most basic one:
template<typename T, size_t S>
struct array {
T t[S];
T& operator[](ptrdiff_t i) { return t[i]; }
T const& operator[](ptrdiff_t i) const { return t[i]; }
};
But as usual, use the tools already written by other people, in this case boost::array. It's also got the advantage of being an aggregate (that's why it has no user declared constructor), so it allows initializing with a brace enclosed list:
boost::array<int, 4> a = {{ 1, 2, 3, 4 }};
you need to pass array bin as an argument in your function.
array always pass by address, therefore you dont need to return any value.
it will automatically show you all changes in your main program
void FunctionAbc(char bin[], int size);
void FuncationAbc(bin, size)
{
for(int i = 7; i >= 0; i--)
{
int ascii='a';
if(2^i-ascii >= 0)
{
bin[i]='1';
ascii=2^i-ascii;
}
else
{
bin[i]='0';
}
}
}
You'll want to pass by reference, as follows:
void modifyBin(char (&bin)[8])
{
/* your function goes here and modifies bin */
}
int main()
{
char bin[8];
modifyBin(bin);
/* bin has been updated */
return 0;
}
I think that everyone else answered this one... use a container instead of an array. Here's the std::string version:
std::string foo() {
int ascii = 'a';
std::string result("00000000");
for (int i=7; i>=0; --i) {
if (2^i-ascii >= 0) {
result[i] = '1';
ascii = 2^i-ascii;
}
}
return result;
}
I'm not really sure if 2^i-ascii is want you want or not. This will be parsed as (2 ^ (i - ascii)) which is a little strange.

Why is my implementation of C++ map not storing values?

I have a class called ImageMatrix, which implements the C++ map in a recursive fashion; the end result is that I have a 3 dimensional array.
typedef uint32_t VUInt32;
typedef int32_t VInt32;
class ImageMatrix
{
public:
ImageMatrixRow operator[](VInt32 rowIndex)
private:
ImageMatrixRowMap rows;
};
typedef std::map <VUInt32, VInt32> ImageMatrixChannelMap;
class ImageMatrixColumn
{
public:
VInt32 &operator[](VUInt32 channelIndex);
private:
ImageMatrixChannelMap channels;
};
typedef std::map<VUInt32, ImageMatrixColumn> ImageMatrixColumnMap;
class ImageMatrixRow
{
public:
ImageMatrixColumn operator[](VUInt32 columnIndex);
private:
ImageMatrixColumnMap columns;
};
typedef std::map<VUInt32, ImageMatrixRow> ImageMatrixRowMap;
Each operator simply returns a map-wrapper class within, like so:
ImageMatrixRow ImageMatrix::operator[](VInt32 rowIndex)
{
return rows[rowIndex];
}
ImageMatrixColumn ImageMatrixRow::operator[](VUInt32 columnIndex)
{
return columns[columnIndex];
}
VInt32 &ImageMatrixColumn::operator[](VUInt32 channelIndex)
{
return channels[channelIndex];
}
Basically, when I set the value as say 100, and test the value to cout, it shows as 0, and not the number to which I had set it.
for (VUInt32 a = 0; a < GetRowCount(); a++)
{
for (VUInt32 b = 0; b < GetColumnCount(); b++)
{
for (VUInt32 c = 0; c < GetChannelCount(); c++)
{
VInt32 value = 100;
matrix[a][b][c] = value;
VInt32 test = matrix[a][b][c];
// pixel = 100, test = 0 - why?
cout << pixel << "/" << test << endl;
}
}
}
Note: I've altered the original code for this example so that it takes up less space, so some syntax errors may occur (please don't point them out).
The following operators return by value, no writes modify the actual data.
ImageMatrixRow ImageMatrix::operator[](VInt32 rowIndex);
ImageMatrixColumn ImageMatrixRow::operator[](VUInt32 columnIndex);
Use:
ImageMatrixRow& ImageMatrix::operator[](VInt32 rowIndex)
ImageMatrixColumn& ImageMatrixRow::operator[](VUInt32 columnIndex)
All your operator[] functions except one return values - they should all return references.
Your ImageMatrixRow and ImageMatrixColumn operator[]() methods return copies, not referecencs.
"Each returns a reference" - are you sure about that?
They look like they return copies of the stored maps, not references to them.
Try, for example:
ImageMatrixRow & ImageMatrix::operator[](VInt32 rowIndex)
Note the & symbol.