I am trying to achieve the following but in a way that follows the c++ standard :
#include <iostream>
using namespace std;
#define MAKE_BOTH(MAKE_FUNC) \
MAKE_FUNC(FIRST) \
MAKE_FUNC(SECOND) \
MAKE_FUNC(THIRD) \
MAKE_FUNC(FOURTH)
#define MAKE_STRINGS(NAME) #NAME,
const char* genericString[] {
MAKE_BOTH(MAKE_STRINGS)
};
#define MAKE_ENUM(NAME) NAME = (1L << __COUNTER__),
enum genericEnum {
MAKE_BOTH(MAKE_ENUM)
};
int main()
{
cout << FIRST << endl;
cout << SECOND << endl;
cout << THIRD << endl;
cout << FOURTH << endl;
}
If you think a while about this code, this creates both, enums and array of "strings" which consists of the same names as enums. The examle code expands to :
const char* genericString[] {
"FIRST",
"SECOND",
"THIRD",
"FOURTH"
};
enum genericEnum {
FIRST = 1L << 0; (1)
SECOND = 1L << 1; (2)
THIRD = 1L << 2; (4)
FOURTH = 1L << 3; (8)
};
Basically the enums are assigned power of 2 values, the question is - is there a relatively simple way of achieving the same thing without using COUNTER ?
The problem is similar to this one:
Counting preprocessor macros
but I have to increase the value of counter each time the macro is used at compile time, I could not figure out how to do it without using the non-standard COUNTER macro.
Please beware the c++ 11 is not an option, but using boost is, I tried the boost approach as well but it is not possible to call the #include directive by a macro which unables me from incrementing the boost preprocessor counter.
You may generate something like this:
enum genericEnum
{
MY_ENUM_BASE=0,
FIRST,
PAST_FIRST= (FIRST<<1)-1,
SECOND,
PAST_SECOND= (SECOND<<1)-1,
THIRD,
PAST_THIRD= (THIRD<<1)-1,
FOURTH,
PAST_FOURTH= (FOURTH<<1)-1,
};
using standard macroprocessor without using COUNTER,
i.e. defining MAKE_ENUM as
#define MAKE_ENUM(NAME) NAME, PAST##_NAME= (NAME<<1)-1,
Related
Suppose I have an header that is meant to be included several times generating code from a template parameterised over a macro DATA. I use it in this way:
#define DATA this
#include <header.hpp>
#undef DATA
#define DATA that
#include <header.hpp>
#undef DATA
#define DATA the_other
#include <header.hpp>
#undef DATA
Is there a way to automate this repeated inclusion given a list of the values of DATA? Something like:
#define DATAS (this, that, the_other)
#include <header.hpp>
#undef DATAS
I tried with some __VA_OPT__ magic, and inside of header.hpp I can isolate the first element of the list and the tail of the list, but the problem is that I cannot redefine DATAS in terms of itself for the next inclusion.
Is this possible at all?
Yes, it is possible.
You can use Boost Preprocessor (which is independent of all other Boost Packages and only has to be downloaded, no library needs to be built or installed) to get the needed ready-to-use macros. You can also try to understand Boost Preprocessor and recreate the needed features.
The example is taken from Ari's answer. It could be expanded to provide several data elements to each iteration, e.g. for initializing the ints and floats with specific values.
// header.hpp - sample header, which uses DATA to create variables
// uses Boost preprocessor only for simple concatenation
// you can use your custom header here
#include <boost/preprocessor/cat.hpp>
int BOOST_PP_CAT(int_, DATA) = 1;
float BOOST_PP_CAT(float_, DATA) = 2.2f;
// main.cpp - wants to define lots of variables
// provides header name, list of symbol suffixes
// repeated.hpp will include header.hpp 3 times with DATA set to this, that and the_other
// (Space after REP_PARAMS is important)
#define REP_PARAMS ("header.hpp")(this, that, the_other)
#include "repeated.hpp"
#undef REP_PARAMS
#include <iostream>
using namespace std;
int main()
{
cout << "int_this: " << int_this << endl;
cout << "int_that: " << int_that << endl;
cout << "int_the_other: " << int_the_other << endl;
cout << "----------------------------------------------------------"
<< endl;
cout << "float_this: " << float_this << endl;
cout << "float_that: " << float_that << endl;
cout << "float_the_other: " << float_the_other << endl;
return 0;
}
// repeated.hpp - helper header
// all the magic
// it mostly extracts the REP_PARAMS sequence
// TODO error-checking, e.g. that REP_PARAMS exists and is a sequence of length two, that second element of REP_PARAMS is a tuple
#if !BOOST_PP_IS_ITERATING
// iteration has not started yet, include used boost headers
// initialize iteration with 3 parameters from 0 to < size of tuple,
// include itself (repeated.hpp)
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/tuple/size.hpp>
#include <boost/preprocessor/seq/seq.hpp>
#define BOOST_PP_ITERATION_PARAMS_1 (3, (0, BOOST_PP_TUPLE_SIZE(BOOST_PP_SEQ_TAIL(REP_PARAMS)), "repeated.hpp"))
#include BOOST_PP_ITERATE()
#else
// set DATA to i-th element in tuple, include specified header (header.hpp)
#define DATA BOOST_PP_TUPLE_ELEM(BOOST_PP_ITERATION(), BOOST_PP_SEQ_TAIL(REP_PARAMS))
#include BOOST_PP_SEQ_HEAD(REP_PARAMS)
#undef DATA
#endif
The maximum list size is 256. By default it is limited to 64, but can be increased with the BOOST_PP_LIMIT_TUPLE macro.
I have to admit I wouldn't even consider using any preprocessing tricks for that. This is a classical scripting problem.
Instead you could write a small script that creates that header for you and inserts that at the beginning of the file. You could then add that as a step in your build system to run it. This technique gives you a LOT of power going forward:
You can add the same header to many scripts rather easily
You can see all the custom headers in a clean json format
You could easily get the script to add multiple #define <key> <value>-s before the include
You could change formatting easily and quickly
Here is an example script that does that:
import json
def prepend_headers(fout, headers):
for header in headers:
include = header['include']
define = header['define']
for k, v in define.items():
fout.write(f'#define {k} {v}\n')
fout.write(f'#include {include}\n')
for k, _ in define.items():
fout.write(f'#undef {k}\n')
fout.write('\n')
def main(configfile):
with open(configfile) as fin:
config = json.load(fin)
input_file = config['input']
with open(input_file) as fin:
input_content = fin.read()
output_file = config['output']
with open(output_file, 'w') as fout:
headers = config['headers']
prepend_headers(fout, headers)
fout.write(input_content)
if __name__ == '__main__':
import sys
configfile = sys.argv[1]
sys.exit(main(configfile))
If you use the following configuration:
{
"input": "class.cpp.template",
"output": "class.cpp",
"headers": [
{
"include": "<header.hpp>",
"define": {
"DATA": "this",
"OBJ": "him"
}
},
{
"include": "<header.hpp>",
"define": {
"DATA": "that"
}
},
{
"include": "<header.hpp>",
"define": {
"DATA": "the_other"
}
}
]
}
And the following template file:
#include <iostream>
class Obj {
};
int main() {
Obj o;
std::cout << "Hi!" << std::endl;
return 0;
}
The result you get is this:
#define DATA this
#define OBJ him
#include <header.hpp>
#undef DATA
#undef OBJ
#define DATA that
#include <header.hpp>
#undef DATA
#define DATA the_other
#include <header.hpp>
#undef DATA
#include <iostream>
class Obj {
};
int main() {
Obj o;
std::cout << "Hi!" << std::endl;
return 0;
}
Using a template class might be annoying, so you might decide to add some hints in the output file so you could "replace" them with every build you run.
This is not doable using preprocessor only. However, it is probably worth mentioning that there is something called X-Macro that could have been used for something close to what you are asking if you weren't using preprocessor macros for each case.
The reason is that it cannot be used here is that you cannot use #define or #include in the definition of a macro.
For example, this is doable for defining this, that and the_other as variables from a file called data.def that has them as a list:
// data.def
ELEMENT(this)
ELEMENT(that)
ELEMENT(the_other)
Then in main.cc:
//main.cc
#define ELEMENT(d) int int_##d = 1;
#include "data.def"
#undef ELEMENT
#define ELEMENT(d) int float_##d = 2.2;
#include "data.def"
#undef ELEMENT
int main() {
std::cout << "int_this: " << int_this << std::endl;
std::cout << "int_that: " << int_that << std::endl;
std::cout << "int_the_other: " << int_the_other << std::endl;
std::cout << "----------------------------------------------------------"
<< std::endl;
std::cout << "float_this: " << float_this << std::endl;
std::cout << "float_that: " << float_that << std::endl;
std::cout << "float_the_other: " << float_the_other << std::endl;
}
Output:
int_this: 1
int_that: 1
int_the_other: 1
---------------------------------------------------------------
float_this: 2
float_that: 2
float_the_other: 2
But something like this is not going to work because you would be defining a macro in another macro:
#define ELEMENT(d) #define DATA d; \
#include "data.def" \
#undef DATA
#undef ELEMENT
There is one function defined in two different ways, one using #define and other using a function. But for the output I am getting different values.
The output is coming out to be 3 -1.
I want to know why using F(x,y) results in different values.
#include<iostream>
#define F(x,y) y-x
using namespace std;
int F2(int x,int y)
{
return y-x;
}
int main()
{
int x=1,y=2, h=2;
cout << F(x+h,y) << " " << F2(x+h,y) << endl;
return 0;
}
First off, you didn't #define a function but a macro. Macros do straight text replacement so the output line is equivalent to:
cout << y-x+h << " " << F2(x+h,y) << endl;
Can you spot the error now?
Classic problem using #define, and one of the main reasons why macros are discouraged. Keep in mind that a macro is little more than a literal substitution, and consider what it expands to:
cout << y-x+h << " " << F2(x+h,y) << endl;
And y-x+h is something very different from y-(x+h).
Always parenthesize uses of macro arguments:
#define F(x,y) ((y)-(x))
#define is a macro directive, not a function. It is just replacing it's occurrences by the macro body. If you do so, you will see that F(x+h,y) is replaced by y-x+h, which is obviously not what you want. The rule for macros is to take all of the parameters and subexpressions into brackes like this:
#define F(x,y) ((y)-(x))
in order to get the correct results.
This way F(x+h,y) will be replaced by ((y)-(x+h)), which is correct
I recently started programming in c++ and I've bumped into a small problem. If I want my output to be structured (let's say that every line starts with a name and then a number) in a way that the names are written normally to the screen (every first letter of every name starts at the beginning of each new line) and I want the numbers that follow to be lined up in a column, how would I do this? I want the programs output to look like this:
Gary 0
LongName 0
VerylongName 0
I want my program to print something in the way above, but with different lengths of names (and the '0' in this case, lined up in a column).
Try the following: if you know the maximum length of all the names you intend to print (e.g. 20), then use the C++ i/o manipulators to set the width of the output (and left-justification). This will force the output to take up max characters.
Code snippet:
#include <iostream>
#include <iomanip>
...
// for each entry
std::cout << std::setw(20) << std::left << "Gary" << 10 << "\n";
...
std::cout << std::flush;
Here's some more information...
I'm shooting in the dark here since you haven't really included much information... HOWEVER one way you can do this is to make sure that you create the columns with padding around the name - and not worry about the numbers. Formatted output is one case where C has an advantage over C++ (IMHO). In C++ you can also do this with something like this:
cout << setw(15) << name << number << "\n";
Bonus points if you figure out ahead of time the maximum length of the name you have and add, say, 4 to it.
Not in the C++ standard library, but still worth mentioning: boost::format. It will let you write printf-like format strings while still being type-safe.
Example:
#include <boost/format.hpp>
#include <iostream>
#include <string>
struct PersonData
{
std::string name;
int age;
};
PersonData persons[] =
{
{"Gary", 1},
{"Whitney", 12},
{"Josephine ", 101}
};
int main(void)
{
for (auto person : persons)
{
std::cout << boost::format("%-20s %5i") % person.name % person.age << std::endl;
}
return 0;
}
Outputs:
Gary 1
Whitney 12
Josephine 101
struct X
{
const char *s;
int num;
} tab[] = {
{"Gary",1},
{"LongName",23},
{"VeryLongName",456}
};
int main(void)
{
for (int i = 0; i < sizeof(tab) / sizeof(struct X); i++ )
{
// C like - example width 20chars
//printf( "%-20s %5i\n", tab[i].s, tab[i].num );
// C++ like
std::cout << std::setw(20) << std::left << tab[i].s << std::setw(5) << std::right << tab[i].num << std::endl;
}
getchar();
return 0;
}
The problem I have is illustrated in the following code.
#include <iostream>
#define X 4
int main()
{
std::cout << "should be 4: " << X << std::endl;
#define Y X + 4
std::cout << "should be 8: " << Y << std::endl;
#undef Y
#define Y X+0
#undef X
#define X Y+1
std::cout << "expecting 5: " << X << std::endl;
}
The error:
test2.cc: In function ‘int main()’:
test2.cc:17: error: ‘X’ was not declared in this scope
The pattern I am trying to emulate is extending a program at code/build level(much like how nginx modules are wired up at compile-time). I need to build up an extensible compile time structure, which is extensible(plugable) by adding #includes to my build, that results in a boost-mpl-vector with a unique name that contains all of my plugins. So if X is the unique end name, X_0, X_1, X_2 are the names that are built up along the way as the vector has mpl-vector push_back applied to it.
I KNOW the abstractions of boost::preprocessor are key, but I don't want to commit the time to researching it just yet, as I'm prototyping part of the system that will eventually be compile-time modularized.
So, for future reference,
Why am I getting an error above ?
What should the correct raw preprocessor pattern look like.
What does the correct boost-preprocessor-library pattern look like.
compiling with g++ -E gives this:
int main()
{
std::cout << "should be 4: " << 4 << std::endl;
std::cout << "should be 8: " << 4 + 4 << std::endl;
std::cout << "expecting 5: " << X+0 +1 << std::endl;
}
So you can see why you get the error.
Why not kill two birds with one stone and use namespaces.
// a.hpp:
namespace a {
const int module_id = 0;
class module_a : extension_module< module_id > { … };
}
#undef last_module
#define last_module a
// b.hpp:
namespace b {
const int last = last_module::module_id + 1;
class module_b : extension_module< module_id > { … };
}
#undef last_module
#define last_module b
This is way less "clever," and leaves a trail of ID's.
However, the modules do need to be included in the same order every time for the ODR to work.
I do not advocate killing any birds.
The problem of your code sample is that you have circular dependency in X and Y macros:
Y is defined as X+0 and X is defined as Y+1. So when macros are expanded (that happens at the point where you use X) you have a problem.
ADD:
It seems that behaviour is this: when expanding macro X inside its definition name X is not defined in preprocessor name space so you see X+0+1 as X expansion.
my_macro << 1 << "hello world" << blah->getValue() << std::endl;
should expand into:
std::ostringstream oss;
oss << 1 << "hello world" << blah->getValue() << std::endl;
ThreadSafeLogging(oss.str());
#define my_macro my_stream()
class my_stream: public std::ostringstream {
public:
my_stream() {}
~my_stream() {
ThreadSafeLogging(this->str());
}
};
int main() {
my_macro << 1 << "hello world" << std::endl;
}
A temporary of type my_stream is created, which is a subclass of ostringstream. All operations to that temporary work as they would on an ostringstream.
When the statement ends (ie. right after the semicolon on the whole printing operation in main()), the temporary object goes out of scope and is destroyed. The my_stream destructor calls ThreadSafeLogging with the data "collected" previously.
Tested (g++).
Thanks/credits to dingo for pointing out how to simplify the whole thing, so I don't need the overloaded operator<<. Too bad upvotes can't be shared.
Couldn't you just derive from ostream and provide your own thread safe implementation? Then you could just do
myCOutObject << 1 << "hello world" << blah->getValue() << std::endl;
And get the exact same functionality without macros and using C++ properly?
No. The problem is that without using function syntax, a macro is limited to only being replaced where it is.
But if you were willing to use function syntax, you can then replace stuff both before and after the args.
my_macro(1 << "hello world" << blah->getValue() << std::endl);
You could by defining MyMacro as:
#define my_macro(args) std::ostreamstring oss; \
oss << args; \
ThreadSafeLogging(oss.str());
Take a look at google-glog, they do this using a temporary object instanciated with a
LOG(INFO) << "log whatever" << 1;
and they also have other interesting macros such as LOG_IF et al.
Considering you have these lines included somewhere in your code, yes it is possible
#include <iostream>
#include <sstream>
__LINE__ macro is defined by all standart compilers.
So we can use it to generate a variable name wich is different each time you use the macro :)
Here is a new version that is seen as a one-statement instruction only:
(EDITED)
#define Var_(Name, Index) Name##Index
#define Var(Name, Index) Var_(Name, Index)
#define my_macro \
for (struct { int x; std::ostringstream oss; } Var(s, __LINE__) = { 0 }; \
Var(s, __LINE__).x<2; ++Var(s, __LINE__).x) \
if (Var(s, __LINE__).x==1) ThreadSafeLogging(Var(s, __LINE__).oss.str()); \
else Var(s, __LINE__).oss
// So you can use it like this
int main()
{
if (4 != 2)
my_macro << 4 << " hello " << std::endl;
my_macro << 2 << " world !" << std::endl;
}
Developper probably won't need to use this macro twice on same line becasue of simplicity of operator <<. But in case you need this, you can switch the use of __LINE__ by __COUNTER__ (which is non standard!). Thanks to Quuxplusone for this tip
Here's another nasty trick I saw somewhere else. It has a significant disadvantage compared to my other answer: you can't use it twice in the same scope because it declares a variable. However, it may still be interesting for other cases where you want to have somemacro foo run something after foo.
#define my_macro \
std::ostringstream oss; \
for (int x=0; x<2; ++x) \
if (x==1) ThreadSafeLogging(oss.str()); \
else oss
int main() {
my_macro << 1 << "hello world" << std::endl;
}
The logging setup I have is quite similar:
bool ShouldLog(const char* file, size_t line, Priority prio);
class LoggerOutput : public std::stringstream {
public:
LoggerOutput(const char* file, size_t line, Priority prio)
: prio(prio)
{
Prefix(file, line, prio);
}
void Prefix(const char* file, size_t line, Priority prio);
~LoggerOutput() {
Flush();
}
void Flush();
private:
Priority prio;
};
#define LOG(Prio) if (!Logging::ShouldLog(__FILE__, __LINE__, Prio)) {} else Logging::LoggerOutput(__FILE__, __LINE__, Prio)
If your logging is disabled, the ostream is never created and little overhead exists. You can configure logging on file name & line number(s) or priority levels. The ShouldLog function can change between invocations, so you could throttle or limit output. The log output uses two functions to modify itself, Prefix that adds a "file:line: (PRIO) " prefix to the line, and Flush() which both flushes it to the log output as a single command and adds a newline to it. In my implementation it always does, but you can make that conditional if one is not already there.