In C++(*), is it possible to have a structure that "defers" some computation until needed (and maybe never does the computation if not necessary)? My use case is as follows: I have roughly a dozen bool variables, each of which is computed with some function call. Following that, there is a rather long (and complex) conditional statement that uses those bool variables in different combinations to determine what action the code will take next.
Here is some contrived sample code to hopefully better illustrate what I'm doing:
bool const b1 = func1(param1,param2,param3);
bool const b2 = func2(param4);
// ...
bool const b15 = func15(param35,param36,param37,param38);
if (b1 && !b5 && (b2 || b3)) { do_something1(); }
else if (b3 && !b15 || (b4 && b9 && b6)) { do_something2(); }
else if (b14 || b10 || (!b11 && b7)) { do_something3(); }
else if (b8) {
if (!b1 || !b6) { do_something4(); }
else if ( /* ... */ ) // ... etc
}
// ... and on and on
That is a purely contrived example, but hopefully it illustrates the idea.
Clearly this code could be re-written without the bools, and the functions called directly in the big conditional statement. But I feel that would make the already not-easy-to-read code even harder to read, and more error prone. And this logic could change, so I feel the bools make it easier to manage from a refactoring perspective as well.
Furthermore, any bool might be referenced multiple times within the conditional; so using the functions directly means execution could be duplicated. (I was thinking std::bind might get me there from a readability perspective; but it would still potentially call any of the funcN() calls multiple times.)
What I'm looking for is the best of both words, like a "deferred" compute. What if instead of being computed and assigned explicitly at the start of the code, I could say, "only evaluate these as needed (and remember the result)". The big conditional statement is such that, generally, not all bools actually need to be computed to determine what happens next. The goal here is improved performance, as this code is called often. So I'm trying to reduce the amount of work done on each iteration.
(*) Preferably C++14 (or older), as that's what my employer is using.
Edit: What about something like this:
#include <iostream>
#include <functional>
//////////////////////////////////////////////////////////////////////////////
class Sum
{
public:
int sum(int const a, int const b) { ++n_calls_; return (a+b); }
int getNCalls() const { return n_calls_; }
private:
int n_calls_ = 0;
};
//////////////////////////////////////////////////////////////////////////////
template <class BoundFunc, typename RetType>
class DeferredCompute
{
public:
DeferredCompute(BoundFunc const& f) : func_(f) { }
RetType operator()()
{
if (!computed_)
{
value_ = func_();
computed_ = true;
}
return value_;
}
private:
bool computed_ = false;
RetType value_;
BoundFunc const& func_;
};
//////////////////////////////////////////////////////////////////////////////
int main(int argc, char* argv[])
{
Sum s;
auto boundSum = std::bind(&Sum::sum, &s, 75, 25);
DeferredCompute<decltype(boundSum), int> deferredSum(boundSum);
// call function directly repeatedly
for (int i=0; i<5; ++i)
{
std::cout << "boundSum()=" << boundSum() << std::endl;
}
std::cout << "s.getNCalls()=" << s.getNCalls() << std::endl;
// should only call once
for (int i=0; i<5; ++i)
{
std::cout << "deferredSum()=" << deferredSum() << std::endl;
}
std::cout << "s.getNCalls()=" << s.getNCalls() << std::endl;
return 0;
}
Output:
boundSum()=100
boundSum()=100
boundSum()=100
boundSum()=100
boundSum()=100
s.getNCalls()=5
deferredSum()=100
deferredSum()=100
deferredSum()=100
deferredSum()=100
deferredSum()=100
s.getNCalls()=6
std::async with the option std::launch::deferred is what you're looking for.
https://en.cppreference.com/w/cpp/thread/async
eg
auto future = std::async(std::launch::deferred, [](){return 5;});
// future isn't calculated yet
auto result = future.get();
// result = 5, and will remain cached while in scope.
At first, I would try using some lambda-closures.
const auto b1 = [&]() { return func1(param1,param2,param3); };
const auto b2 = [&]() { return func2(param4); };
// ...
const auto b15 = [&]() { return func15(param35,param36,param37,param38); };
if (b1() && !b5() && (b2() || b3())) { do_something1(); }
...
If you need to cache the bool results but not for the entire
lifetime of the program (static), this solution could
make it (three levels of lambda-closure; it's "Inception").
/**
g++ -std=c++17 -o prog_cpp prog_cpp.cpp \
-pedantic -Wall -Wextra -Wconversion -Wno-sign-conversion \
-g -O0 -UNDEBUG -fsanitize=address,undefined
**/
#include <iostream>
void
test(int i)
{
auto cache=[](auto expr)
{
return [expr, res=false, done=false]() mutable
{
if(!done) { res=expr(); done=true; }
return res;
};
};
auto b1=cache([&]() { std::cout << "(eval b1)"; return i>2; });
auto b2=cache([&]() { std::cout << "(eval b2)"; return i<5; });
std::cout << "1: b1=" << b1() << " b2=" << b2() << '\n';
std::cout << "2: b1=" << b1() << " b2=" << b2() << '\n';
}
int
main()
{
for(int i=0; i<6; ++i)
{
std::cout << "~~~~~~~~\n";
test(i);
}
return 0;
}
/**
~~~~~~~~
1: b1=(eval b1)0 b2=(eval b2)1
2: b1=0 b2=1
~~~~~~~~
1: b1=(eval b1)0 b2=(eval b2)1
2: b1=0 b2=1
~~~~~~~~
1: b1=(eval b1)0 b2=(eval b2)1
2: b1=0 b2=1
~~~~~~~~
1: b1=(eval b1)1 b2=(eval b2)1
2: b1=1 b2=1
~~~~~~~~
1: b1=(eval b1)1 b2=(eval b2)1
2: b1=1 b2=1
~~~~~~~~
1: b1=(eval b1)1 b2=(eval b2)0
2: b1=1 b2=0
**/
For the sake of readability and maintainability you could organise the program as a state machine. That provides you with the benefit of separating the state transitions and actions from one another, plus it should be reasonably simple to rewire the logic later should the necessity arise.
See here for some examples:
C++ code for state machine
What if instead of being computed and assigned explicitly at the start of the code, I could say, "only evaluate these as needed (and remember the result)"
/// #brief only evaluate these as needed (and remember the result)
class lazy final
{
mutable std::future<bool> value_;
public:
template<typename Functor>
lazy(Functor &&f)
: value_{ std::async(std::launch::deferred,
std::forward<Functor>(f)) }
{
}
operator bool() const
{
return value_.get();
}
};
client code:
auto b1 = lazy::lazy{[&]{ return func1(param1,param2,param3); }};
auto b2 = lazy::lazy{[&]{ return func2(param4); }};
// ...
bool const b15 = lazy::lazy{[&]{ return func15(param35,param36,param37,param38); }};
// rest remains the same as your contrieved example
I have not compiled this code. If working in c++14 (as you mention) you may need a factory function similar to this:
template<typename Functor>
auto make_lazy(Functor&& f) { return lazy<Functor>(std::forward<Functor>(f)); }
The only thing that changes is the declaration of your bX variables. You may also consider adding code that tells you how often each lazy evaluation is called in practice, declaring those bX variables first, and launching them immediately, in parallel, instead of in a deferred manner. But only do that after you measure performance both ways.
Related
I want to have a class for PCI bus locations. For the sake of discussion, these come in three forms:
[domain]:[bus]:[device].[function]
[domain]:[bus]:[device]
[bus]:[device].[function]
and let's say each field is a non-negative integral value (let's even say unsigned just to make things simple).
I'm scratching my head regarding how to define this class. I could use std::optionals for the domain and function fields; but then, they're not both optional. I could use a variant with 3 types, but then I need to define separate types, which overlap a lot. I could just hold 4 unsigneds and a 3-value enum for which format is in effect - but that's quite a bit of hassle, and I'd need getter and to make the class opaque. Same thing if I try to use a union somehow.
It seems like every choice I make, it's going to be an iffy class. How can I minimize my displeasure with it?
Note: Any language standard version is ok for the answer, although I doubt C++20 would give you anything.
Building upon my comment, I was wondering if something like this could work:
enum class pci_format { domain_function, domain, function };
template <pci_format E> struct tag { };
class pci_location {
public:
pci_location (tag<pci_format::domain_function>, unsigned domain, unsigned bus,
unsigned device, unsigned function)
: format_(pci_format::domain_function)
, domain_(domain)
, bus_(bus)
, device_(device)
, function_(function)
{ }
// Repeat for other values of pci_format.
pci_format format () const { return format_; }
bool has_domain () const {
return (format_ == pci_format::domain_function)
or (format_ == pci_format::domain);
}
unsigned domain () const {
if (not has_domain()) { throw std::runtime_error("Domain not available."); }
return domain_;
}
// Repeat for other fields.
private:
pci_format format_;
unsigned domain_;
unsigned bus_;
unsigned device_;
unsigned function_
};
You would basically create a specific constructor for each PCI "format". Of course you could also store each unsigned as an std::optional<unsigned>, but that would force users to "dereference" each optional even if they knew for sure that it must contain a value.
One way or another, they'll have to check what "format" the location is in, so it seems to me that using an enum for this is more user friendly. Then users only have to check once and know exactly which fields are available.
I guess you could layer a visitor on top of all this so they can simply provide code to execute for each "format":
struct pci_location_visitor {
virtual void visit (tag<pci_format::domain_function>, pci_location const & obj) = 0;
// Repeat for other enum values.
};
// Add to pci_location:
void accept (pci_location_visitor & visitor) {
switch (format_) {
case pci_format::domain_function:
return visitor.visit(tag<pci_format::domain_function>{}, *this);
default: throw std::runtime_error("Format not supported for visitation.");
}
}
Then on top of that you could create a visitor that can be constructed from a bunch of callables, i.e. lambdas, so that this all can be used like below:
pci_location const & loc = getIt();
auto printSomething = make_pci_location_visitor(
[](tag<pci_format::domain_function>, pci_location const & e) { std::cout << e.domain(); }
, [](tag<pci_format::domain>, pci_location const & e) { std::cout << e.bus(); }
, [](tag<pci_format::function>, pci_location const & e) { std::cout << e.function(); }
);
loc.accept(printSomething);
For an example of how such a visitor could be constructed, see the overloaded class in the std::visit example on cppreference.com.
As requested in comments... given that I have no particular requirements how the users would prefer to use this class, given C++14, I would be doing something generic along the lines of:
#include <array>
#include <climits>
#include <iostream>
#include <stdexcept>
class pci_location_t {
public:
struct dbdf {
unsigned int domain;
unsigned int bus;
unsigned int device;
unsigned int function;
};
struct dbd {
unsigned int domain;
unsigned int bus;
unsigned int device;
};
struct bdf {
unsigned int bus;
unsigned int device;
unsigned int function;
};
pci_location_t(dbdf v) : domain(v.domain), bus(v.bus), device(v.device), function(v.function) {}
pci_location_t(dbd v) : domain(v.domain), bus(v.bus), device(v.device), function(INVALID) {}
pci_location_t(bdf v) : domain(INVALID), bus(v.bus), device(v.device), function(v.function) {}
template <typename dbdf_f, typename dbd_f, typename bdf_f>
auto visit(dbdf_f dbdf_fun, dbd_f dbd_fun, bdf_f bdf_fun) const {
if (domain == INVALID) {
if (function == INVALID) {
throw std::domain_error("Wrong PCI location format");
}
return bdf_fun(bdf{bus, device, function});
} else if (function == INVALID) {
return dbd_fun(dbd{domain, bus, device});
} else {
return dbdf_fun(dbdf{domain, bus, device, function});
}
}
private:
friend pci_location_t invalid_location();
pci_location_t() : domain(INVALID), bus(INVALID), device(INVALID), function(INVALID) {}
const static unsigned int INVALID = UINT_MAX;
unsigned int domain;
unsigned int bus;
unsigned int device;
unsigned int function;
};
pci_location_t invalid_location() { return pci_location_t{}; }
int main() {
std::array<pci_location_t, 4> locations = {
pci_location_t(pci_location_t::dbdf{1, 2, 3, 4}),
pci_location_t(pci_location_t::dbd{1, 2, 3}),
pci_location_t(pci_location_t::bdf{2, 3, 4}),
invalid_location()
};
try {
for (auto& l : locations) {
l.visit(
[] (auto dbdf) {
std::cout << dbdf.domain << ":" << dbdf.bus << ":" << dbdf.device << "." << dbdf.function << std::endl;
},
[] (auto dbd) {
std::cout << dbd.domain << ":" << dbd.bus << ":" << dbd.device << std::endl;
},
[] (auto bdf) {
std::cout << bdf.bus << ":" << bdf.device << "." << bdf.function << std::endl;
}
);
}
std::cout << "Done!" << std::endl;
} catch(const std::exception& e) {
std::cout << e.what() << std::endl;
}
return 0;
}
(you can check it on Coliru).
Feel free to use optionals or a separate format field if you don't like special values.
I'd make both the domain and the function optional (I don't really care how, as long as it's effective), and just enforce the only-one-missing condition as a class invariant. That is, only the functions that can change any of the fields need to perform the check and signal possible errors back to the user. No need to bloat your code with variants, or with dynamically interpreted unsigned int arrays. KISS.
There's an class named PlotCurve. It describes a chart as a container of points and operations on them. A data for PlotCurve is gotten from the class RVDataProvider. Important thing is that the amount of points that is provided by RVDataProvider may be big (more than 1kk) so RVDataProvider returns a read-only pointer to Y data (X data can be calculated by index of the pointer) to improve the perfomance.
The main problem is that RVDataProvider has two different methods for two types:
class RVDataProvider : public QObject, public IRVImmutableProvider
{
public:
// ...
ReadonlyPointer<float> getSignalDataFloat(int signalIndex, quint64 start, quint64 count) override;
ReadonlyPointer<double> getSignalDataDouble(int signalIndex, quint64 start, quint64 count) override;
// ...
}
ReadonlyPointer<T> is only a read-only wrapper of a C-style pointer.
In order to get a curve's range of values (for looking for min-max, painting them on the canvas, etc) I am supposed to declare different functions too.
class PlotCurve : public QObject
{
public:
// ...`
virtual ReadonlyPointer<float> getFloatPointer(quint64 begin, quint64 length) const;
virtual ReadonlyPointer<double> getDoublePointer(quint64 begin, quint64 length) const;
// ...
}
It leads to using switch statement in the client code and its changes if the new available type of data is added.
switch (dataType())
{
case RVSignalInfo::DataType::Float: {
auto pointer = getFloatPointer(begin, length);
Q_ASSERT(!(pointer).isNull()); \
for (quint64 i = 0; i < (length); ++i) { \
auto y = (pointer)[i]; \
if (y < (minY)) { (minY) = y; continue; } \
if (y > (maxY)) { (maxY) = y; } \
}
} break;
case RVSignalInfo::DataType::Double: {
auto pointer = getDoublePointer(begin, length);
Q_ASSERT(!(pointer).isNull()); \
for (quint64 i = 0; i < (length); ++i) { \
auto y = (pointer)[i]; \
if (y < (minY)) { (minY) = y; continue; } \
if (y > (maxY)) { (maxY) = y; } \
}
} break;
// ...
}
Is there a way to get rid of dependencies to a client code? Three thing came to my mind:
1) Create Iterator type that would be a wrapper of ReadonlyPointer. Nope - performance is decreased to 10+ times because of iterator's virtual functions.
2) Create a traverse method that would be perform some function to every value in some range. Nope again - the most optimized version using function pointers is two times slower than switch statement in client code.
3) Make the class PlotCurve template. In this way I can't add different PlotCurves to the one container like it is now.
Unfortunately, I don't see much which can be done for OPs problem.
At best, the similar looking parts of cases could be moved to
a macro
a function template
to prevent code duplication.
For demonstration, I resembled OPs problem with the following sample code:
enum DataType { Float, Double };
struct Data {
std::vector<float> dataFloat;
std::vector<double> dataDouble;
DataType type;
Data(const std::vector<float> &data): dataFloat(data), type(Float) { }
Data(const std::vector<double> &data): dataDouble(data), type(Double) { }
};
With a function template, processing could look like this:
namespace {
// helper function template for process()
template <typename T>
std::pair<double, double> getMinMax(const std::vector<T> &values)
{
assert(values.size());
double min = values[0], max = values[0];
for (const T &value : values) {
if (min > value) min = value;
else if (max < value) max = value;
}
return std::make_pair(min, max);
}
} // namespace
void process(const Data &data)
{
std::pair<double, double> minMax;
switch (data.type) {
case Float: minMax = getMinMax(data.dataFloat); break;
case Double: minMax = getMinMax(data.dataDouble); break;
}
std::cout << "range: " << minMax.first << ", " << minMax.second << '\n';
}
Live Demo on coliru
With a macro it would appear even more compact:
void process(const Data &data)
{
std::pair<double, double> minMax;
switch (data.type) {
#define CASE(TYPE) \
case TYPE: { \
assert(data.data##TYPE.size()); \
minMax.first = minMax.second = data.data##TYPE[0]; \
for (const double value : data.data##TYPE) { \
if (minMax.first > value) minMax.first = value; \
else if (minMax.second < value) minMax.second = value; \
} \
} break
CASE(Float);
CASE(Double);
#undef CASE
}
std::cout << "range: " << minMax.first << ", " << minMax.second << '\n';
}
Live Demo on coliru
Many people (me included) consider macros in C++ as dangerous. In opposition to everything else, macros are not subject of namespaces or scopes. This can cause confusion if any identifier becomes unexpectedly subject of preprocessing. In worst case, the unintendedly modified code passes compiler and leads to unexpected behavior in runtime. (My sad experience.)
However, this is not expected in this case (assuming the code would be part of a source file).
I would've preferred a third alternative which places the repeated code inside of process(). A lambda came in my mind but lambdas can not (yet) be templated: SO: Can lambda functions be templated?.
A local template (functor) isn't alternative. It's prohibited as well: SO: Why can't templates be declared in a function?.
After feedback of OP, a note about X macros: It's an ancient technique in C to prevent redundancy of data.
A "data table" is defined where each row is a "call" of a (here not defined) macro X which contains all features.
To use the data table:
define a macro X which uses just the arguments which are needed in the individual case (and ignores the rest)
#include the data table
#undef X.
The sample again:
void process(const Data &data)
{
std::pair<double, double> minMax;
switch (data.type) {
#define X(TYPE_ID, TYPE) \
case TYPE_ID: { \
assert(data.data##TYPE_ID.size()); \
minMax.first = minMax.second = data.data##TYPE_ID[0]; \
for (const double value : data.data##TYPE_ID) { \
if (minMax.first > value) minMax.first = value; \
else if (minMax.second < value) minMax.second = value; \
} \
} break;
#include "Data.inc"
#undef X
}
std::cout << "range: " << minMax.first << ", " << minMax.second << '\n';
}
where Data.inc is:
X(Float, float)
X(Double, double)
X(Int, int)
Live Demon on coliru
Although, this macro-trickery makes a bit scary – this is very convenient concerning maintenance. If a new data type has to be added, a new X() line in Data.inc (and, of course, a re-compile) is all what's necessary. (The compiler / build chain will hopefully consider all dependencies of sources from Data.inc. We never faced problems with this in Visual Studio.)
Lambdas are an awesome way to create reusable code inside a function/method without polluting the parent class. They're a very functional replacement for C-style macros most of the time.
However, there's one bit of syntactic sugar from macros that I can't seem to replicate with a lambda, and that's the ability to exit from the containing function. For example, if I need to return while checking the range of a series of ints, I can do that easily with a macro:
const int xmin(1), xmax(5);
#define CHECK_RANGE(x) { if((x) < xmin || (x) > xmax) return false; }
bool myFunc(int myint) {
CHECK_RANGE(myint);
int anotherint = myint + 2;
CHECK_RANGE(anotherint);
return true;
}
Obviously this is an oversimplified example, but the basic premise is that I'm performing the same check over and over on different variables, and I think it's more readable to encapsulate the check and related exits. Still, I know that macros aren't very safe, especially when they get really complex. However, as far as I can tell, trying to do the equivalent lambda requires awkward additional checks like so:
const int xmin(1), xmax(5);
auto check_range = [&](int x) -> bool { return !(x < xmin || x > xmax); };
bool myFunc(int myint) {
if(!check_range(myint)) return false;
int anotherint = myint + 2;
if(!check_range(anotherint)) return false;
return true;
}
Is there a way to do this with a lambda? Or am I missing some alternative solution?
Edit: I recognize that returning from inside a macro is generally a bad idea unless significant precautions are taken. I'm just wondering if it's possible.
You are correct--there's no way to return from the caller from inside a lambda. Since a lambda can be captured and stored to be called later, from inside an arbitrary caller, doing so would result in unpredictable behavior.
class Foo
{
Foo(std::function<void(int)> const& callMeLater) : func(callMeLater) {}
void CallIt(int* arr, int count)
{
for (index = count; index--;)
func(count);
// do other stuff here.
}
std::function<void(int)> func;
};
int main()
{
auto find3 = [](int arr)
{
if (arr == 3)
return_from_caller; // making up syntax here.
};
Foo foo(find3);
};
Is there a way to do this with a lambda?
Not exactly like the macro but your lambda, instead of returning a bool, can throw a special exception (of type bool, by example)
auto check_range
= [](int x) { if ( (x < xmin) || (x > xmax) ) throw bool{false}; };
and the function myFunc() can intercept this special type
bool myFunc (int myint)
{
try
{
check_range(myint);
int anotherint = myint + 2;
check_range(anotherint);
return true;
}
catch ( bool e )
{ return e; }
}
For a single check_range() call, this is (I suppose) a bad idea; if you have a lot of calls, I suppose can be interesting.
The following is a full working example
#include <iostream>
constexpr int xmin{1}, xmax{5};
auto check_range
= [](int x) { if ( (x < xmin) || (x > xmax) ) throw bool{false}; };
bool myFunc (int myint)
{
try
{
check_range(myint);
int anotherint = myint + 2;
check_range(anotherint);
return true;
}
catch ( bool e )
{ return e; }
}
int main ()
{
std::cout << myFunc(0) << std::endl; // print 0
std::cout << myFunc(3) << std::endl; // print 1
std::cout << myFunc(7) << std::endl; // print 0
}
No better way to do this than just to use the return value of the lambda and then return from the calling function. Macros are ew for this.
As it stands in C++, that is the idiomatic way to exit from a function that uses another condition to determine whether or not to exit.
Not C++11, but people have hacked C++2a coroutines to basically do this.
It would look a bit like:
co_await check_range(foo);
where the co_await keyword indicates that in some cases, this coroutine could return early with an incomplete result. In your cases, this incomplete result would be non-resumabable error.
The playing around I saw was with optionals, and required using a shared ptr, but things may improve before it is standardized.
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) << ','; } );
I have the following Python snippet that I would like to reproduce using C++:
from itertools import count, imap
source = count(1)
pipe1 = imap(lambda x: 2 * x, source)
pipe2 = imap(lambda x: x + 1, pipe1)
sink = imap(lambda x: 3 * x, pipe2)
for i in sink:
print i
I've heard of Boost Phoenix, but I couldn't find an example of a lazy transform behaving in the same way as Python's imap.
Edit: to clarify my question, the idea is not only to apply functions in sequence using a for, but rather to be able to use algorithms like std::transform on infinite generators. The way the functions are composed (in a more functional language like dialect) is also important, as the next step is function composition.
Update: thanks bradgonesurfing, David Brown, and Xeo for the amazing answers! I chose Xeo's because it's the most concise and it gets me right where I wanted to be, but David's was very important into getting the concepts through. Also, bradgonesurfing's tipped Boost::Range :).
Employing Boost.Range:
int main(){
auto map = boost::adaptors::transformed; // shorten the name
auto sink = generate(1) | map([](int x){ return 2*x; })
| map([](int x){ return x+1; })
| map([](int x){ return 3*x; });
for(auto i : sink)
std::cout << i << "\n";
}
Live example including the generate function.
I think the most idiomatic way to do this in C++ is with iterators. Here is a basic iterator class that takes an iterator and applies a function to its result:
template<class Iterator, class Function>
class LazyIterMap
{
private:
Iterator i;
Function f;
public:
LazyIterMap(Iterator i, Function f) : i(i), f(f) {}
decltype(f(*i)) operator* () { return f(*i); }
void operator++ () { ++i; }
};
template<class Iterator, class Function>
LazyIterMap<Iterator, Function> makeLazyIterMap(Iterator i, Function f)
{
return LazyIterMap<Iterator, Function>(i, f);
}
This is just a basic example and is still incomplete as it has no way to check if you've reached the end of the iterable sequence.
Here's a recreation of your example python code (also defining a simple infinite counter class).
#include <iostream>
class Counter
{
public:
Counter (int start) : value(start) {}
int operator* () { return value; }
void operator++ () { ++value; }
private:
int value;
};
int main(int argc, char const *argv[])
{
Counter source(0);
auto pipe1 = makeLazyIterMap(source, [](int n) { return 2 * n; });
auto pipe2 = makeLazyIterMap(pipe1, [](int n) { return n + 1; });
auto sink = makeLazyIterMap(pipe2, [](int n) { return 3 * n; });
for (int i = 0; i < 10; ++i, ++sink)
{
std::cout << *sink << std::endl;
}
}
Apart from the class definitions (which are just reproducing what the python library functions do), the code is about as long as the python version.
I think the boost::rangex library is what you are looking for. It should work nicely with the new c++lambda syntax.
int pipe1(int val) {
return 2*val;
}
int pipe2(int val) {
return val+1;
}
int sink(int val) {
return val*3;
}
for(int i=0; i < SOME_MAX; ++i)
{
cout << sink(pipe2(pipe1(i))) << endl;
}
I know, it's not quite what you were expecting, but it certainly evaluates at the time you want it to, although not with an iterator iterface. A very related article is this:
Component programming in D
Edit 6/Nov/12:
An alternative, still sticking to bare C++, is to use function pointers and construct your own piping for the above functions (vector of function pointers from SO q: How can I store function pointer in vector?):
typedef std::vector<int (*)(int)> funcVec;
int runPipe(funcVec funcs, int sinkVal) {
int running = sinkVal;
for(funcVec::iterator it = funcs.begin(); it != funcs.end(); ++it) {
running = (*(*it))(running); // not sure of the braces and asterisks here
}
return running;
}
This is intended to run through all the functions in a vector of such and return the resulting value. Then you can:
funcVec funcs;
funcs.pushback(&pipe1);
funcs.pushback(&pipe2);
funcs.pushback(&sink);
for(int i=0; i < SOME_MAX; ++i)
{
cout << runPipe(funcs, i) << endl;
}
Of course you could also construct a wrapper for that via a struct (I would use a closure if C++ did them...):
struct pipeWork {
funcVec funcs;
int run(int i);
};
int pipeWork::run(int i) {
//... guts as runPipe, or keep it separate and call:
return runPipe(funcs, i);
}
// later...
pipeWork kitchen;
kitchen.funcs = someFuncs;
int (*foo) = &kitchen.run();
cout << foo(5) << endl;
Or something like that. Caveat: No idea what this will do if the pointers are passed between threads.
Extra caveat: If you want to do this with varying function interfaces, you will end up having to have a load of void *(void *)(void *) functions so that they can take whatever and emit whatever, or lots of templating to fix the kind of pipe you have. I suppose ideally you'd construct different kinds of pipe for different interfaces between functions, so that a | b | c works even when they are passing different types between them. But I'm going to guess that that's largely what the Boost stuff is doing.
Depending on the simplicity of the functions :
#define pipe1(x) 2*x
#define pipe2(x) pipe1(x)+1
#define sink(x) pipe2(x)*3
int j = 1
while( ++j > 0 )
{
std::cout << sink(j) << std::endl;
}