<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7098284592115366563</id><updated>2024-09-01T22:57:07.163-07:00</updated><category term="C++"/><category term="C++11"/><category term="Boost"/><category term="metaprogramming"/><category term="TBB"/><category term="Containers"/><category term="D"/><category term="Go"/><category term="Linux"/><category term="Networking"/><category term="iOS"/><title type='text'>Developer&#39;s Perspective</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://dev-perspective.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default'/><link rel='alternate' type='text/html' href='http://dev-perspective.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Eugene</name><uri>http://www.blogger.com/profile/15405098005234713619</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7098284592115366563.post-3925243217328040707</id><published>2019-09-23T21:40:00.003-07:00</published><updated>2019-09-23T21:40:47.639-07:00</updated><title type='text'>This blog has moved!</title><content type='html'>I&#39;ve moved my blog to https://eyakubovich.github.io/</content><link rel='replies' type='application/atom+xml' href='http://dev-perspective.blogspot.com/feeds/3925243217328040707/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dev-perspective.blogspot.com/2019/09/this-blog-has-moved.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/3925243217328040707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/3925243217328040707'/><link rel='alternate' type='text/html' href='http://dev-perspective.blogspot.com/2019/09/this-blog-has-moved.html' title='This blog has moved!'/><author><name>Eugene</name><uri>http://www.blogger.com/profile/15405098005234713619</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7098284592115366563.post-7945781468478988155</id><published>2016-07-04T12:34:00.000-07:00</published><updated>2016-07-04T12:36:39.385-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Containers"/><category scheme="http://www.blogger.com/atom/ns#" term="Linux"/><title type='text'>Break open that container!</title><content type='html'>If you happen to follow the world of IT infrastructure, DevOps, or just happen to be an IT professional, you, no doubt, have heard of the container revolution.
Propelled into popularity by Docker, containers (and the ecosystem around them) seem to be the answer to all things ops.
I, too, like the elegance with which containers solve many of the problems around shipping and running software.&lt;br /&gt;
&lt;br /&gt;
Great, but let&#39;s pause for a second to see what problems containers actually solve. I contend that they solve three distinct problems:&lt;br /&gt;
&lt;br /&gt;
1. Ability to package software in its entirety and ship it from the publisher to the consumer. Basically it&#39;s about distributing a tarball with all the bits and then running those bits without worrying what else is on the target machine. It&#39;s solves the dependency hell problem that package mangers were never quite able to do.&lt;br /&gt;
&lt;br /&gt;
2. Running the software in isolation from other processes/containers on the system. Your contained service can now have its own PID space and its very own TCP port 80. If you happen to blindly schedule services onto machines (e.g. if using an orchestration system like Kubernetes), you can sleep soundly knowing that the services won&#39;t conflict.&lt;br /&gt;
&lt;br /&gt;
3. Constraining the resources. When running a container, you can cap the CPU, memory, and I/O that the processes inside the container are allowed to consume.&lt;br /&gt;
&lt;br /&gt;
As I&#39;ve said before, these are three distinct problems and yet all the container systems try to couple them into a single solution. This is unfortunate for two reasons:&lt;br /&gt;
&lt;br /&gt;
1. Often times, I do not need all three when running a service or an application. In fact, most often I care just about (1) -- pulling an image and running it, without worrying about the dependencies that will get sprinkled onto my system. Or I might want to dedicate a machine to my production database and thus do not need isolation or resource constraints. Yet I would still like to use Docker hub to install the bits. Docker, rkt, systemd-nspawn and others do provide knobs to turn off bits and pieces but it is more painful than it needs to be. On the flip side, I may want to isolate and constrain an application that I installed via apt-get or yum (and no, unshare(1) and cgexec(1) do not quite cut it).&lt;br /&gt;
&lt;br /&gt;
2. It does not allow independent innovation in these areas. The coupling prevents me (without hoop jumping) from using Docker to pull and execute the app while using rkt for resource isolation. This feels very un-UNIXy.&lt;br /&gt;
&lt;br /&gt;
It is easy to see how we got to where we are. Containers were initially viewed as lightweight VMs and so inherited the same semantics as their heavier cousins. VMs, in turn, coupled the aforementioned areas due to their implementations. I think it is safe to say that most people no longer view containers as lightweight VMs. The notion of a &quot;systems container&quot; has been superseded by an &quot;application container&quot;. It would be prudent for organisations like &lt;a href=&quot;https://www.opencontainers.org/&quot;&gt;Open Container Initiative&lt;/a&gt; to consider defining interfaces that would allow innovation of individual components of the container runtimes.</content><link rel='replies' type='application/atom+xml' href='http://dev-perspective.blogspot.com/feeds/7945781468478988155/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dev-perspective.blogspot.com/2016/07/break-open-that-container.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/7945781468478988155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/7945781468478988155'/><link rel='alternate' type='text/html' href='http://dev-perspective.blogspot.com/2016/07/break-open-that-container.html' title='Break open that container!'/><author><name>Eugene</name><uri>http://www.blogger.com/profile/15405098005234713619</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7098284592115366563.post-4702879272017296776</id><published>2014-05-08T14:05:00.001-07:00</published><updated>2014-05-09T09:13:32.529-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="C++11"/><title type='text'>Factory functions and their return types</title><content type='html'>Suppose we need to write a factory function that constructs a runtime polymorphic object. For the purposes of this post, let&#39;s say we want to construct a concrete shape object -- a rectangle, triangle, or an ellipse. Here are our basic declarations:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;struct shape {
&amp;nbsp; &amp;nbsp; virtual ~shape() {}
};

struct ellipse : shape {
&amp;nbsp; &amp;nbsp; ellipse(int rad_a, int rad_b) {}
};

struct triangle : shape {
&amp;nbsp; &amp;nbsp; triangle(int base, int height) {}
};

struct rectangle : shape {
&amp;nbsp; &amp;nbsp; rectangle(int width, int height) {}
};
&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Basic stuff. Now for the factory function:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;enum class shape_type { ellipse, triangle, rectangle };

struct rect {
&amp;nbsp; &amp;nbsp; int w, h;
};

??? make_shape(shape_type type, rect bounds);
&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
What should make_shape return. A pointer to shape, of course, but which kind. Should it be a raw pointer or a smart pointer like std::unique_ptr and std::shared_ptr. C++11 heavily advocates against raw pointers and I completely agree. That leaves us with a unique_ptr or a shared_ptr. I believe that in vast majority of situations there&#39;s a single owner of an object so that begs for returning unique_ptr. At least few other people are of the same opinion: &lt;a href=&quot;http://stackoverflow.com/questions/13062106/returning-pointer-from-factory&quot;&gt;here&lt;/a&gt;&amp;nbsp;and &lt;a href=&quot;http://herbsutter.com/2013/05/30/gotw-90-solution-factories/&quot;&gt;here&lt;/a&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The argument goes that a shared_ptr can be constructed from a unique_ptr&amp;amp;&amp;amp; so this will also work just fine for the less common shared ownership cases:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;std::shared_ptr&amp;lt;shape&amp;gt; s = make_shape(shape_type::ellipse, { 3, 5 });
&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
While that is certainly true, there is a performance problem with this. C++11 encourages us to use std::make_shared&amp;lt;T&amp;gt; to construct shared ownership objects. Most std::make_shared implementations use a single dynamic memory allocation for both the object and the pointer control block (that stores the ref count). Not only does that save on overhead of calling &#39;new&#39; twice, it also improves the cache locality by keeping the two close.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
That benefit is clearly lost with conversion from unique_ptr to shared_ptr. I would therefore argue that factory functions should come in two flavors: a unique and a shared kind:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;std::unique_ptr&amp;lt;shape&amp;gt; make_unique_shape(shape_type type, rect bounds);
std::shared_ptr&amp;lt;shape&amp;gt; make_shared_shape(shape_type type, rect bounds);
&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
We now have two functions that do almost identical work. To avoid code duplication, we should factor out common behavior, right? Right but it turns out to be trickier than I expected. What we want is a helper function that is parameterized on make_shared or make_unique (or similar till will have it in C++14). The solution I came up with uses good old tag dispatching.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
First, declare the tags but have them also know their associated smart pointer type:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;struct shared_ownership {
&amp;nbsp; &amp;nbsp; template &amp;lt;typename T&amp;gt; using ptr_t = std::shared_ptr&amp;lt;T&amp;gt;;
};

struct unique_ownership {
&amp;nbsp; &amp;nbsp; template &amp;lt;typename T&amp;gt; using ptr_t = std::unique_ptr&amp;lt;T&amp;gt;;
};&amp;nbsp;
&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;
Next, we add two overloads to do the actual construction:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;typename T, typename... Args&amp;gt;
std::unique_ptr&amp;lt;T&amp;gt; make_with_ownership(unique_ownership, Args... args) {
&amp;nbsp; &amp;nbsp; // until we have make_unique in C+14
&amp;nbsp; &amp;nbsp; return std::unique_ptr&amp;lt;T&amp;gt;(new T(std::forward&amp;lt;Args&amp;gt;(args)...));
}
&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;typename T, typename... Args&amp;gt;
std::shared_ptr&amp;lt;T&amp;gt; make_with_ownership(shared_ownership, Args... args) {
&amp;nbsp; &amp;nbsp; return std::make_shared&amp;lt;T&amp;gt;(std::forward&amp;lt;Args&amp;gt;(args)...);
}
&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Finally, we can put it all together to create a generic make_shape along with make_unique_shape and make_shared_shape:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;typename OwnTag&amp;gt;
typename OwnTag::template ptr_t&amp;lt;shape&amp;gt; make_shape(shape_type type, rect bounds, OwnTag owntag) {
&amp;nbsp; &amp;nbsp; switch( type ) {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case shape_type::ellipse:
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return make_with_ownership&amp;lt;ellipse&amp;gt;(owntag, bounds.w / 2, bounds.h / 2);

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case shape_type::triangle:
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return make_with_ownership&amp;lt;triangle&amp;gt;(owntag, bounds.w, bounds.h);

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; case shape_type::rectangle:
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return make_with_ownership&amp;lt;rectangle&amp;gt;(owntag, bounds.w, bounds.h);
&amp;nbsp; &amp;nbsp; }
}

inline std::unique_ptr&amp;lt;shape&amp;gt; make_unique_shape(shape_type type, rect bounds) {
&amp;nbsp; &amp;nbsp; return make_shape(type, bounds, unique_ownership());
}

inline std::shared_ptr&amp;lt;shape&amp;gt; make_shared_shape(shape_type type, rect bounds) {
&amp;nbsp; &amp;nbsp; return make_shape(type, bounds, shared_ownership());
}
&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;
If you look at the return type of make_shape, it should make you cringe with disgust. Yeah, no bonus points for elegant syntax here. I also dislike the verbose name make_with_ownership. Nevertheless, I believe having a generic function for both unique and shared construction is extremely valuable. I would love to hear proposals for a better implementation and suggestions for a more concise name.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
As always, the code is available on &lt;a href=&quot;https://github.com/eyakubovich/blog-code/tree/master/factory&quot;&gt;GitHub&lt;/a&gt;.&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://dev-perspective.blogspot.com/feeds/4702879272017296776/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dev-perspective.blogspot.com/2014/05/factory-functions-and-their-return-types.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/4702879272017296776'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/4702879272017296776'/><link rel='alternate' type='text/html' href='http://dev-perspective.blogspot.com/2014/05/factory-functions-and-their-return-types.html' title='Factory functions and their return types'/><author><name>Eugene</name><uri>http://www.blogger.com/profile/15405098005234713619</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7098284592115366563.post-1823836865803352202</id><published>2014-03-23T15:43:00.000-07:00</published><updated>2014-03-23T15:43:33.425-07:00</updated><title type='text'>forkfs: making any directory into a throw away directory</title><content type='html'>I recently needed to work on two git branches simultaneously. My particular use case required me to make small changes to both branches, rebuild and run. These were temporary changes that I was going to blow away at the end. One approach could have been to have two clones of the repo but that would have required me to rebuild my project from scratch for the second working copy (it was boost which is large). Having run into the same predicament before, I decided to create a script to &quot;fork&quot; a directory.&lt;br /&gt;
&lt;br /&gt;
The script, called forkfs, works as follows. Suppose you are in your bash session in directory foo:&lt;br /&gt;
&lt;pre class=&quot;brush: shell&quot;&gt;~/foo$ ls
bar
&lt;/pre&gt;
&lt;br /&gt;
You then execute forkfs which launches a new bash session and changes your prompt to remind you that you are forked:&lt;br /&gt;
&lt;pre class=&quot;brush: shell&quot;&gt;~/foo$ sudo ~/bin/forkfs
(forkfs) ~/foo$ ls
bar
&lt;/pre&gt;
&lt;br /&gt;
So far it looks like nothing has changed but if we start making changes to the contents of foo, they&#39;ll only be visible in our forked session:&lt;br /&gt;
&lt;pre class=&quot;brush: shell&quot;&gt;(forkfs) ~/foo$ touch baz
(forkfs) ~/foo$ ls
bar baz
&lt;/pre&gt;
&lt;br /&gt;
Open up another bash session and do an ls there:&lt;br /&gt;
&lt;pre class=&quot;brush: shell&quot;&gt;~/foo$ ls
bar
&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
When you exit out of your forkfs session, all your changes will be lost! You can also make multiple forks of the same directory, just not a fork of a fork. The forkfs script is available on &lt;a href=&quot;https://github.com/eyakubovich/blog-code/blob/master/forkfs/forkfs&quot;&gt;GitHub&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3&gt;
Words Of Caution&lt;/h3&gt;
Be careful where your fork begins. If you&#39;re using it for multiple git branches like I was, be sure to fork at the repository directory -- same place that houses the .git directory. Otherwise git will be confused outside of forked session.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Under The Hood&lt;/h3&gt;
&lt;div&gt;
The script makes use of two technologies that are also used by &lt;a href=&quot;https://www.docker.io/&quot;&gt;Docker&lt;/a&gt;: aufs and mount namespaces. &lt;a href=&quot;http://aufs.sourceforge.net/&quot;&gt;Aufs&lt;/a&gt;&amp;nbsp;is a &lt;a href=&quot;http://en.wikipedia.org/wiki/Union_mount&quot;&gt;union filesystem&lt;/a&gt;&amp;nbsp;which takes multiple source directories and combines them into a single destination directory. For example, one can mount /home/johndoe such that it&#39;s a union of /home/john and /home/doe directories. When you make changes in /home/johndoe, aufs uses a preconfigured policy to figure out which underlying directory gets the changes. One such policy allows forkfs to create Copy-On-Write functionality. When forkfs is forking ~/foo:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
1. It creates an empty temporary directory, e.g. /tmp/tmp.Gb33ro1lrU&lt;/div&gt;
&lt;div&gt;
2. It mounts ~/foo (marked as readonly) + /tmp/tmp.Gb33ro1lrU (marked as read-write) into ~/foo:&lt;/div&gt;
&lt;pre class=&quot;brush: shell&quot;&gt;mount -t aufs -o br=/tmp/tmp.Gb33ro1lrU=rw:~/foo=ro none ~/foo
&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Since ~/foo was marked as read only, all the writes go to the temporary directory, achieving copy-on-write.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Notice that the aufs was mounted over ~/foo. An unfortunate consequence of this is that the original ~/foo is no longer accessible. Moreover, it will not be possible to create other forks of ~/foo. This is where mount namespaces come to the rescue.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Mount namespaces allow a process to inherit all of the parent&#39;s mounts but have any further mounts not be visible by its parent. Linux actually has other namespaces of which a process can get a private copy: IPC, network, host/domain names, PIDs. &lt;a href=&quot;https://linuxcontainers.org/&quot;&gt;Linux containers (&lt;span id=&quot;goog_32538743&quot;&gt;&lt;/span&gt;LXC&lt;span id=&quot;goog_32538744&quot;&gt;&lt;/span&gt;)&lt;/a&gt;&amp;nbsp;makes use of these to provide light-weight virtualization.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
unshare is a handy command to get a process running with a private namespace. forkfs uses &quot;unshare -m bash&quot; to get a bash running with a private mount namespace. It then executes aufs mount without having the rest of the system seeing the fork.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3&gt;
Future Work&lt;/h3&gt;
&lt;div&gt;
If I have time, I&#39;d like to add ability to create named forks and then be able to come back to them (like Python&#39;s virtualenv).&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h3&gt;
Acknowledgements&lt;/h3&gt;
&lt;div&gt;
Special thanks goes to Vlad Didenko for helping me out with bash nuances.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://dev-perspective.blogspot.com/feeds/1823836865803352202/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dev-perspective.blogspot.com/2014/03/forkfs-making-any-directory-into-throw.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/1823836865803352202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/1823836865803352202'/><link rel='alternate' type='text/html' href='http://dev-perspective.blogspot.com/2014/03/forkfs-making-any-directory-into-throw.html' title='forkfs: making any directory into a throw away directory'/><author><name>Eugene</name><uri>http://www.blogger.com/profile/15405098005234713619</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7098284592115366563.post-4684308318937897294</id><published>2014-01-03T10:26:00.001-08:00</published><updated>2014-01-03T10:26:31.804-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="iOS"/><title type='text'>LastPark: my first iPhone app gone wrong</title><content type='html'>I decided to venture out into the unknown -- iOS development. My first app -- LastPark -- saves the last location where the car was parked. I was solely trying to scratch a personal itch as I often forget on what street or what end of the parking lot I parked at. There are plenty of apps out there that allow you to mark the location of the vehicle but that requires remembering to do that before you&#39;re lost! Then there are Bluetooth LE devices that you can purchase and install in your car. When you shut your engine the device turns off and the app loses connectivity to it, causing it to save the location. $99 &lt;a href=&quot;http://www.automatic.com/&quot;&gt;Automatic&lt;/a&gt;&amp;nbsp;will also provide a slew of other features while the $25 &lt;a href=&quot;http://findmycarsmarter.com/&quot;&gt;Find My Car Smarter&lt;/a&gt;&amp;nbsp;is very basic.&lt;br /&gt;
&lt;br /&gt;
However my car already has the Bluetooth built in and moreover connects to my iPhone every time I get in to provide me with hands free calling. Why, I thought, would I need to buy another Bluetooth device when I got all the parts already installed. This is when I decided to write LastPark. (Technically I had to spend $99 to join the Apple Developer Program -- the same price as the fancy Automatic).&lt;br /&gt;
&lt;br /&gt;
Unfortunately getting access to plain old Bluetooth (not the new Low Energy one) is not exactly easy in iOS. It seems like the only way was to use a private framework (undocumented). The upside is that a few people have already gone this route and there&#39;s even a &lt;a href=&quot;https://github.com/michaeldorner/BeeTee&quot;&gt;demo project on GitHub&lt;/a&gt; that I used as a starting point. The downside is that Apple does not allow apps that use private frameworks in the AppStore. Not a biggie for me as I was developing it for my own use.&lt;br /&gt;
&lt;br /&gt;
What killed this app was the inability to run it in the background. After some time in the background state the app gets suspended and doesn&#39;t get woken up for Bluetooth notifications. I tried specifying various background mode preferences in the plist but to no avail. I realize that Apple tries to improve the battery life by limiting the amount of work the apps can do in the background. However I believe it should be more liberal in allowing apps to register for notifications of ambient activities. These registrations probably take just a few bytes in some table inside a daemon (that&#39;s running anyway) and don&#39;t take much resources.&lt;br /&gt;
&lt;br /&gt;
I&#39;ve &lt;a href=&quot;https://github.com/eyakubovich/LastPark&quot;&gt;released&lt;/a&gt; what I got on GitHub. Any comments on how to get this to work as desired would be greatly appreciated.</content><link rel='replies' type='application/atom+xml' href='http://dev-perspective.blogspot.com/feeds/4684308318937897294/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dev-perspective.blogspot.com/2014/01/lastpark-my-first-iphone-app-gone-wrong.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/4684308318937897294'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/4684308318937897294'/><link rel='alternate' type='text/html' href='http://dev-perspective.blogspot.com/2014/01/lastpark-my-first-iphone-app-gone-wrong.html' title='LastPark: my first iPhone app gone wrong'/><author><name>Eugene</name><uri>http://www.blogger.com/profile/15405098005234713619</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7098284592115366563.post-7315567599340791023</id><published>2013-09-03T19:56:00.000-07:00</published><updated>2013-09-03T19:57:26.316-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="C++11"/><title type='text'>Lazy approach to assignment operators</title><content type='html'>Most of the time we don&#39;t have to worry about defining copy/move constructors and assignment operators -- the compiler happily generates them for us. Sometimes, however, we must do the dirty work ourselves and code them up manually, often together with the destructor. By hand crafting the assignment operators, we sometimes gain extra efficiency (e.g. std::vector re-using the memory in copy-assignment) but most of the time the code just ends up looking like a copy/paste job of destructor and copy/move constructor.&lt;br /&gt;
&lt;br /&gt;
If we&#39;re not lazy and define a swap function, we can use the&amp;nbsp;&lt;a href=&quot;http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Copy-and-swap&quot;&gt;copy/swap&lt;/a&gt;&amp;nbsp;idiom to get a free pass on the copy-assignment operator. Not so for the move-assignment. &lt;a href=&quot;http://efesx.com/2009/09/04/implementing-assignment-operator-using-copy-constructor/&quot;&gt;This post&lt;/a&gt; from 2009 provides an interesting trick to reuse destructor/copy constructor to implement the copy-assignment without the swap function. Here&#39;s the code provided by that post:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;struct A {
&amp;nbsp; &amp;nbsp; A ();
&amp;nbsp; &amp;nbsp; A (const A &amp;amp;a);
&amp;nbsp; &amp;nbsp; virtual A &amp;amp;operator= (const A &amp;amp;a);
&amp;nbsp; &amp;nbsp; virtual ~A ();
};

A &amp;amp;A::operator= (const A &amp;amp;a) {
&amp;nbsp; &amp;nbsp; if (this != &amp;amp;a) {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; this-&amp;gt;A::~A(); // explicit non-virtual destructor
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; new (this) A(a); // placement new
&amp;nbsp; &amp;nbsp; }
&amp;nbsp; &amp;nbsp; return *this;
}
&lt;/pre&gt;
&lt;br /&gt;
The author does warn about the downsides of using this trick but I think the concerns are fairly minor. The technique can also be extended for the move-assignment operator:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;typename T, typename U&amp;gt;
A &amp;amp;A::operator= (A &amp;amp;&amp;amp;a) {
&amp;nbsp; &amp;nbsp; if (this != &amp;amp;a) {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; this-&amp;gt;A::~A(); // explicit non-virtual destructor
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; new (this) A(std::move(a)); // placement new
&amp;nbsp; &amp;nbsp; }
&amp;nbsp; &amp;nbsp; return *this;
}
&lt;/pre&gt;
&lt;br /&gt;
And can be generalized into a utility function that can cover both of those uses. The function and its usage is shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;typename T, typename U&amp;gt;
T&amp;amp; assign(T* obj, U&amp;amp;&amp;amp; other) {
&amp;nbsp; &amp;nbsp; if( obj != &amp;amp;other ) {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; obj-&amp;gt;T::~T();
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; new (static_cast&amp;lt;void*&amp;gt;(obj)) T(std::forward&amp;lt;U&amp;gt;(other));
&amp;nbsp; &amp;nbsp; }
&amp;nbsp; &amp;nbsp; return *obj;
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;struct A {
&amp;nbsp; &amp;nbsp; A ();
&amp;nbsp; &amp;nbsp; A (const A&amp;amp; a);
&amp;nbsp; &amp;nbsp; A(A&amp;amp;&amp;amp; a);
&amp;nbsp; &amp;nbsp; virtual ~A ();
&amp;nbsp; &amp;nbsp; A&amp;amp; operator= (const A&amp;amp; a) {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return assign(this, a);
&amp;nbsp; &amp;nbsp; }
&amp;nbsp; &amp;nbsp; A&amp;amp; operator=(A&amp;amp;&amp;amp; a) {

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return assign(this, std::move(a));
&amp;nbsp; &amp;nbsp; }
};
&lt;/pre&gt;
&lt;br /&gt;
One very nice side affect of this approach is that it becomes possible to create a copy/move assignment operators for those classes that can otherwise only be copy/move constructable. For example, consider:
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;struct X {
&amp;nbsp; &amp;nbsp;int&amp;amp; i;
};
&lt;/pre&gt;
&lt;br /&gt;
The compiler will generate a copy/move constructor pair but will delete the corresponding assignment operators. You&#39;d be hard pressed to define them yourself as well. But destroy/construct trick allows us to side step such limitations!
&lt;br /&gt;
&lt;br /&gt;
Note that assign&#39;s second argument is a &lt;a href=&quot;http://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers&quot;&gt;&quot;universal reference&quot;&lt;/a&gt;&amp;nbsp;and will bind to anything. Thus the assign function can actually by used to implement any assignment operator (not just copy/move) as long as the corresponding constructor is available.
&lt;br /&gt;
&lt;br /&gt;
Now suppose that struct X is located in a third party library and you don&#39;t want to modify it to add the assignment operators. By defining a utility class assignable&amp;lt;T&amp;gt;, we can add the desired functionality externally:
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;typename T&amp;gt;
class assignable : public T {
public:
&amp;nbsp; &amp;nbsp; using T::T;

&amp;nbsp; &amp;nbsp; assignable(T const&amp;amp; other) :
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; T(other) {
&amp;nbsp; &amp;nbsp; }

&amp;nbsp; &amp;nbsp; assignable(T&amp;amp;&amp;amp; other) :
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; T(std::move(other)) {
&amp;nbsp; &amp;nbsp; }

&amp;nbsp; &amp;nbsp; template &amp;lt;typename U&amp;gt;
&amp;nbsp; &amp;nbsp; assignable&amp;amp; operator=(U&amp;amp;&amp;amp; other) {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return assign(this, std::forward&amp;lt;U&amp;gt;(other));
&amp;nbsp; &amp;nbsp; }
};

// and usage:
struct X {
&amp;nbsp; &amp;nbsp; X(int&amp;amp; ii) : i(ii) {}
&amp;nbsp; &amp;nbsp; int&amp;amp; i;
};

int i = 1, j = 2;
assignable&amp;lt;X&amp;gt; x(i);
x = assignable&amp;lt;X&amp;gt;(j);
&lt;/pre&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;
&lt;/pre&gt;
This approach makes me wonder if the language should support a way of auto generating the copy/move assignments not member-wise but from destructor and constructor. We could then opt-in to such goodness like this:
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;Foo&amp;amp; operator=(Foo&amp;amp;&amp;amp;) = default(via_constructor);
Foo&amp;amp; operator=(Foo const&amp;amp;) = default(via_constructor);
&lt;/pre&gt;
&lt;br /&gt;
The code (along with a work around for compilers not supporting inheritable constructors) is available on &lt;a href=&quot;https://github.com/eyakubovich/cxx-sandbox/blob/master/assign.h&quot;&gt;GitHub&lt;/a&gt;.
</content><link rel='replies' type='application/atom+xml' href='http://dev-perspective.blogspot.com/feeds/7315567599340791023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dev-perspective.blogspot.com/2013/09/lazy-approach-to-assignment-operators.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/7315567599340791023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/7315567599340791023'/><link rel='alternate' type='text/html' href='http://dev-perspective.blogspot.com/2013/09/lazy-approach-to-assignment-operators.html' title='Lazy approach to assignment operators'/><author><name>Eugene</name><uri>http://www.blogger.com/profile/15405098005234713619</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7098284592115366563.post-3601836306955662033</id><published>2013-06-04T11:28:00.002-07:00</published><updated>2013-06-04T11:29:58.316-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Networking"/><title type='text'>Folding SSL/TLS into TCP to gain efficiency</title><content type='html'>In this post, I will divert from my usual topic of C++ to jog down my thoughts about TCP and SSL. &amp;nbsp;I have limited knowledge of networking and even more limited understanding of security so my ramblings here might be full of flaws and security holes. Nevertheless, I thought it would be fun to share a random idea on how to get the web to run a little faster.&lt;br /&gt;
&lt;h2&gt;
Background&lt;/h2&gt;
SSL is used by HTTPS (and others) to secure the pipe between the browser and the web server. Once used primarily by sites performing financial transactions (banks, ecommerce), it is more and more used by services which require a login (e.g. Gmail, Twitter). As such, a fast HTTPS connection is more important than ever. HTTPS connection starts out as a TCP 3-way handshake, followed by an SSL/TLS handshake. Let&#39;s take a quick look at each one in more detail.&lt;br /&gt;
&lt;h2&gt;
TCP 3-way Handshake&lt;/h2&gt;
TCP 3-way handshake starts with the client sending a SYN packet to the server. Upon receipt, the server replies with its own SYN packet but also piggybacks the acknowledgement (that it received the client&#39;s SYN) in the same packet. Thus, the server replies with a SYN-ACK packet. Finally, when the client receives the server&#39;s SYN-ACK packet, it replies with an ACK to signify that it has received the SYN from the server. At this point the TCP connection is established and the client can immediately start sending data. Therefore, the latency cost of connection establishment is 1 round-trip in the case of the first message sent by the client (as in HTTP case) and 1.5 round-trips in the case where the server is the first to speak its mind (e.g. POP3).&lt;br /&gt;
&lt;br /&gt;
There are a number of reasons for SYN-packets and 3-way handshake. First, the SYN (synchronize) packets are used to exchange the initial sequence numbers that will be used by both parties to ensure transport reliability (and flow control). Second, it is used to detect old (duplicate) SYN packets arriving at the host by asking the sender to validate them (see &lt;a href=&quot;http://www.ietf.org/rfc/rfc793.txt&quot;&gt;RFC793&lt;/a&gt;, Figure 8). Lastly, the handshake is used as a security measure. For example, suppose a TCP server is sitting behind a firewall that only accepts traffic from IP 66.55.44.33. If the connection would become established with the very first SYN packet, an attacker could create TCP/IP packet whose source IP would be 66.55.44.33 instead of his own and put the data in that very packet. The server would receive the SYN+data, create a connection and forward the data to the application. By sending a SYN-ACK and expecting it to echo the sequence number in the final ACK packet, the server can be certain that the source IP was not spoofed.&lt;br /&gt;
&lt;br /&gt;
Interestingly,&amp;nbsp;&lt;a href=&quot;http://www.ietf.org/rfc/rfc793.txt&quot;&gt;RFC793&lt;/a&gt;&amp;nbsp;does allow data to be included in the SYN packets. However, for the reasons described above, it requires the stack to queue the data for the delivery to the application only after the successful 3-way handshake.&lt;br /&gt;
&lt;h2&gt;
SSL/TLS Handshake&lt;/h2&gt;
Once a TCP connection is established, SSL handshake begins with the client sending ClientHello message containing version, random bits, and a list of cipher-suites it supports (e.g. AES-256). It can also include a number of extension fields. The server responds with ServerHello containing selected version and cipher-suite, random bits and extension fields. The server then follows up with its certificate and ServerHelloDone message. The three messages can end up within one TCP packet. Finally, the client sends the cipher key (actually bits that will be used to compute it) and both the client and server send messages to switch from plain-text to encrypted communication.&lt;br /&gt;
&lt;br /&gt;
The takeaway here is that just like a TCP handshake, SSL also requires several packets to be exchanged before the application level communication can commence. These exchanges add another 2 round-trips worth of latency.&lt;br /&gt;
&lt;h2&gt;
Proposal: Combine TCP and SSL Handshakes&lt;/h2&gt;
What if TCP and SSL handshakes could be combined to save a round trip? Conceptually, TCP resides at layer 4 (transport) of the OSI reference model. Since it seems that nobody can quite figure out where SSL fits in, it doesn&#39;t seem all that unnatural to create &quot;Secure TCP&quot; protocol (not unlike IPSec). SSL handshake can then begin with the very first SYN packet:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Client &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Server&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;~~~~~~ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ~~~~~~&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;TCP SYN, SSL ClientHello --&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;-- TCP SYN+ACK, SSL ServerHello+Cert+ServerHelloDone&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;TCP ACK, SSL ClientKeyExch+... --&amp;gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;-- TCP ACK, SSL ChangeCipherSpec+...&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
This scheme would almost have to push SSL processing into the kernel (since that&#39;s where TCP is usually handled) but perhaps some hybrid solution could be implemented (e.g. PKI done in userspace).&lt;br /&gt;
&lt;h2&gt;
Backward Compatibility&lt;/h2&gt;
Recall that the original TCP specification (&lt;a href=&quot;http://www.ietf.org/rfc/rfc793.txt&quot;&gt;RFC793&lt;/a&gt;) allows data to be exchanged in SYN packets (I am not sure, though, how OS kernels actually handle this situation). If a server not supporting this new scheme were to receive a SYN/ClientHello packet, it would simply respond with the usual SYN-ACK and queue the ClientHello until it receives the final ACK. The client would see a SYN-ACK packet with no data, send an ACK and wait for the ServerHello to come a bit later.&lt;br /&gt;
&lt;h2&gt;
Security Considerations&lt;/h2&gt;
One security vulnerability with the proposed scheme is that it would make &lt;a href=&quot;http://en.wikipedia.org/wiki/SYN_flood&quot;&gt;SYN flood&lt;/a&gt; DoS attack easier to execute. Since the data from ClientHello would need to be stored in the embryonic connection, it would use up more memory, causing the system to run out of memory earlier than today. The new scheme would also be incompatible with &lt;a href=&quot;http://en.wikipedia.org/wiki/SYN_cookies&quot;&gt;SYN cookies&lt;/a&gt;, a countermeasure against the SYN flood attack.&lt;br /&gt;
&lt;h2&gt;
What about SSL Sessions?&lt;/h2&gt;
SSL actually has mechanisms for turning the 4-way handshake into a 2-way handshake for all but the first connection (by a client caching a server cookie). This can continue to function as is, and, combined with the proposed scheme would make the whole TCP/SSL connection establishment take just a single round trip.&lt;br /&gt;
&lt;h2&gt;
TCP Fast Open&lt;/h2&gt;
A recent proposal from Google, called&amp;nbsp;&lt;a href=&quot;http://research.google.com/pubs/pub37517.html&quot;&gt;TCP Fast Open&lt;/a&gt;, is designed to reduce the overhead of the TCP 3-way handshake. In a similar way to SSL sessions, TCP Fast Open generates a cryptographically signed cookie that the client can store and then use for subsequent connections. While the first client-server connection uses the full 3-way handshake, subsequent ones can have data sent and delivered to the application via the SYN packet. While TCP Fast Open should be able to peacefully coexist with this proposal, it would not help in reducing the number of round trips for SSL&#39;s session establishment.&lt;br /&gt;
&lt;h2&gt;
Related Work&lt;/h2&gt;
A &lt;a href=&quot;http://tools.ietf.org/html/draft-agl-tcpm-sadata-00&quot;&gt;proposal&lt;/a&gt; from 2009, attempts to solve a similar problem in a generic way. It proposes the ability to include a limited amount of data (up to 64 bytes) in the SYN-ACK packet coming from the server. It could then be used to include a first part of the handshake. However, although the proposal aims to be generic (not tied to a specific upper layer protocol), it does not allow data to be included in the client&#39;s SYN packet, making it incompatible with protocols that rely on the client to initiate the handshake. The 64 byte limitation may also not be enough for SSL needs.&lt;br /&gt;
&lt;h2&gt;
Conclusion&lt;/h2&gt;
With more services utilizing HTTPS and a growing number of wireless devices whose communication latencies are often greater than those of their wired counterparts, it is imperative to minimize the number of round-trips made during connection establishment. While I am assuming that the proposed scheme is not adequate for implementation, I hope it can be used as food for thought on how to improve performance of the future web applications.</content><link rel='replies' type='application/atom+xml' href='http://dev-perspective.blogspot.com/feeds/3601836306955662033/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dev-perspective.blogspot.com/2013/06/folding-ssltls-into-tcp-to-gain.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/3601836306955662033'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/3601836306955662033'/><link rel='alternate' type='text/html' href='http://dev-perspective.blogspot.com/2013/06/folding-ssltls-into-tcp-to-gain.html' title='Folding SSL/TLS into TCP to gain efficiency'/><author><name>Eugene</name><uri>http://www.blogger.com/profile/15405098005234713619</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7098284592115366563.post-6826180693263620772</id><published>2012-10-06T18:23:00.000-07:00</published><updated>2012-10-07T10:27:52.438-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Boost"/><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="C++11"/><title type='text'>On List Comprehension in C++</title><content type='html'>Many programming languages take inspiration from the language of mathematics and emulate &lt;a href=&quot;http://en.wikipedia.org/wiki/Set-builder_notation&quot;&gt;Set-builder Notation&lt;/a&gt;. Take for instance the following set, specified by the set-builder notation:&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://www.codecogs.com/eqnedit.php?latex=\left%20\{%20x^{2}%20|%20x%20\in%20\mathbb{N},%20x%20%3E%205%20\right%20\}&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://latex.codecogs.com/gif.latex?\left \{ x^{2} \mid x \in \mathbb{N}, x &amp;gt; 5 \right \}&quot; title=&quot;\left \{ x^{2} \mid x \in \mathbb{N}, x &amp;gt; 5 \right \}&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Haskell, for example, has &lt;a href=&quot;http://en.wikipedia.org/wiki/List_comprehension#Haskell&quot;&gt;List Comprehension&lt;/a&gt; syntax which allows for expressing the above set as:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;[x^2 | x &amp;lt;- [0..], x &amp;gt; 5]&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
C# supports &lt;a href=&quot;http://en.wikipedia.org/wiki/Language_Integrated_Query&quot;&gt;LINQ&lt;/a&gt;, which borrows SQL notation to express the same idea. C++ does not have syntactic support for expressing set-builder notation but numerous attempts by library authors have tried to fill the gap. Take a look at &lt;a href=&quot;http://stackoverflow.com/questions/232222/is-there-a-linq-library-for-c&quot;&gt;this&lt;/a&gt;&amp;nbsp;StackOverflow thread for links to projects emulating LINQ in C++. Others have &lt;a href=&quot;http://smellegantcode.wordpress.com/tag/c0x/&quot;&gt;noted&lt;/a&gt;&amp;nbsp;that Boost.Range can already be used for this task. The following code expresses the aforementioned set (at least for a subset of natural numbers):&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;using namespace boost;

auto sq = counting_range(0, 1000)
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | filtered([](int x) { return x &amp;gt; 5; })
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; | transformed([](int x) { return x*x; });
&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;
There is one place though, where Boost.Range approach falls short. Set-builder notation can be used with more than one variable:&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;a href=&quot;http://www.codecogs.com/eqnedit.php?latex=\left%20\{%20x%20@plus;%20y%20|%20x%20\in%20\mathbb{N},%20y%20\in%20\mathbb{N},%20x^2%20@plus;%20y^2%20%3C%20100%20\right%20\}&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://latex.codecogs.com/gif.latex?\left \{ x + y \mid x \in \mathbb{N}, y \in \mathbb{N}, x^2 + y^2 &amp;lt; 100 \right \}&quot; title=&quot;\left \{ x + y \mid x \in \mathbb{N}, y \in \mathbb{N}, x^2 + y^2 &amp;lt; 100 \right \}&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
In this case, a&amp;nbsp;&lt;a href=&quot;http://en.wikipedia.org/wiki/Cartesian_product&quot;&gt;Cartesian product&lt;/a&gt;&amp;nbsp;of the sets is taken and the elements of that product are &quot;filtered&quot; and &quot;transformed&quot;. The Range library, however, does not provide a way to generate the Cartesian product. So let&#39;s look at what it would take to offer such&amp;nbsp;functionality. This will give us a chance to not only experiment with Boost.Range but also play around with variadic templates.&lt;br /&gt;
&lt;br /&gt;
Since we&#39;ll be making ample use of C++11&#39;s variadic templates, it&#39;s important to understand them. If you need a good primer, the best thing is to watch Andrei&#39;s Alexandrescu&#39;s &lt;a href=&quot;http://channel9.msdn.com/Events/GoingNative/GoingNative-2012/Variadic-Templates-are-Funadic&quot;&gt;Variadic Templates are Funadic&lt;/a&gt;&amp;nbsp;(or at least the first 30 mins of it).&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
The Goal&lt;/h2&gt;
Let&#39;s begin by looking at what we are after:&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;std::vector&amp;lt;int&amp;gt; xx = { 1, 2, 3 };
std::vector&amp;lt;char&amp;gt; yy = { &#39;a&#39;, &#39;b&#39;, &#39;c&#39; };
std::vector&amp;lt;double&amp;gt; zz = { 0.1, 0.2, 0.3 };

auto r = cartesian(xx, yy, zz)
       | xfiltered([](int x, char y, double z) { return x &amp;gt; 1 &amp;amp;&amp;amp; y &amp;lt; &#39;c&#39;; })
       | xtransformed([](int x, char y, double z) { return x + int(y) + z; });
&lt;/pre&gt;
&lt;div&gt;
cartesian() function takes any number of ranges and returns a range of std::tuple&#39;s. In the example above, cartesian(xx, yy, zz) returns a range of std::tuple&amp;lt;int&amp;amp;, char&amp;amp;, double&amp;amp;&amp;gt; and will have nine elements: (1, &#39;a&#39;, 0.1), (1, &#39;a&#39;, 0.2), (1, &#39;a&#39;, 0.3), (1, &#39;b&#39;, 0.1), and so on. xfiltered() and xtransformed() are analogous to filtered() and transformed() except that they allow the lambda to accept multiple arguments instead of a single tuple. Without them, the code would look like this:&lt;/div&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;auto r = cartesian(xx, yy, zz)
       | filtered([](std::tuple&amp;lt;int&amp;amp;, char&amp;amp;, double&amp;amp;&amp;gt; x) { return std::get&amp;lt;0&amp;gt;(x) &amp;gt; 1 &amp;amp;&amp;amp; std::get&amp;lt;1&amp;gt;(x) &amp;lt; &#39;c&#39;; })
       | transformed([](std::tuple&amp;lt;int&amp;amp;, char&amp;amp;, double&amp;amp;&amp;gt; x) { return std::get&amp;lt;0&amp;gt;(x) + int(std::get&amp;lt;1&amp;gt;(x)) + std::get&amp;lt;2&amp;gt;(x); });
&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;h2&gt;
Boost Ranges&lt;/h2&gt;
&lt;/div&gt;
&lt;div&gt;
Boost Ranges aim to raise the level of abstraction when dealing with sequences by providing a single object representing an interval. However, unlike ranges proposed by Alexandrescu in &lt;a href=&quot;http://www.slideshare.net/rawwell/iteratorsmustgo&quot;&gt;Iterators Must Go&lt;/a&gt; &lt;a href=&quot;http://blip.tv/boostcon/boostcon-2009-keynote-2452140&quot;&gt;keynote&lt;/a&gt;, Boost Ranges are a leaky abstraction. They leak the underlying iterators by requiring the range to expose them via boost::begin(rng) and boost::end(rng). This requirement will force us to define a cartesian_iterator and demonstrate the downside of the leak. The principal advantage of leaking the iterators though is the ability to&amp;nbsp;inter-operate&amp;nbsp;with existing algorithms designed to work with iterators.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;h2&gt;
Getting Started&lt;/h2&gt;
Before getting into the details of the cartesian_iterator that will do all of the heavy-lifting, let&#39;s look at the big picture:&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;using namespace boost;

// To be filled in later
template &amp;lt;typename... Rs&amp;gt;
class cartesian_iterator;

// Boost.Range provides iterator_range class which constructs a range
// from a begin and end iterator pair
template &amp;lt;typename... Rs&amp;gt;
using cartesian_range = iterator_range&amp;lt;cartesian_iterator&amp;lt;Rs...&amp;gt;&amp;gt;;

// Our &quot;public&quot; function that takes any number of ranges and
// constructs a cartesian_range
template &amp;lt;typename... Rs&amp;gt;
typename cartesian_range&amp;lt;Rs...&amp;gt;::type cartesian(Rs&amp;amp;... rs) {
&amp;nbsp; &amp;nbsp; typedef cartesian_iterator&amp;lt;Rs...&amp;gt; iter_t;
&amp;nbsp; &amp;nbsp; return cartesian_range&amp;lt;Rs...&amp;gt;(iter_t(rs...), iter_t(rs..., 0));
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;div&gt;
The first step in defining the cartesian_iterator is to decide what will be its value_type. As I mentioned above, it will be the std::tuple of references to the types of the ranges. The code below defines a meta-function to extract the reference type of a range and then uses it to define the value_type of cartesian_iterator:
&lt;/div&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;typename R&amp;gt;
struct range_reference {
&amp;nbsp; &amp;nbsp; typedef typename boost::range_iterator&amp;lt;R&amp;gt;::type iter;
&amp;nbsp; &amp;nbsp; typedef typename iter::reference type;
};

template &amp;lt;typename... Rs&amp;gt;
struct value_type {
&amp;nbsp; &amp;nbsp; typedef std::tuple&amp;lt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; typename range_reference&amp;lt;Rs&amp;gt;::type...
&amp;nbsp; &amp;nbsp; &amp;gt; type;
};
&lt;/pre&gt;
&lt;div&gt;
To ease the task of writing an iterator, we&#39;ll be using Boost.Iterators, in particular&amp;nbsp;&lt;a href=&quot;http://www.boost.org/doc/libs/1_51_0/libs/iterator/doc/iterator_facade.html&quot;&gt;iterator_facade&lt;/a&gt; class. We just have to derive from it and implement 3 functions. Here&#39;s what the derivation looks like:&lt;/div&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;typename... Rs&amp;gt;
class cartesian_iterator : public boost::iterator_facade&amp;lt;
&amp;nbsp; &amp;nbsp; cartesian_iterator&amp;lt;Rs...&amp;gt;, &amp;nbsp;// pass self per CRTP
&amp;nbsp; &amp;nbsp; typename value_type&amp;lt;Rs...&amp;gt;::type, &amp;nbsp;// value_type
&amp;nbsp; &amp;nbsp; boost::forward_traversal_tag, &amp;nbsp;// iterator category
&amp;nbsp; &amp;nbsp; typename value_type&amp;lt;Rs...&amp;gt;::type &amp;nbsp;// reference -- same as value_type!
&amp;gt;
&lt;/pre&gt;
&lt;div&gt;
Note that the reference type will be std::tuple&amp;lt;...&amp;gt; and not std::tuple&amp;lt;...&amp;gt;&amp;amp;. The reason being is that when dereferencing, we&#39;ll return a temporary std::tuple&amp;lt;...&amp;gt; since the cartesian_range is not stored in memory per se. Obviously, returning a temporary from a function with a reference return type is a bad idea.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Next stop -- deciding what data members will be needed in the iterator. Consider what happens when asked to generate a cartesian_range over two ranges -- {1, 2} and {&#39;a&#39;, &#39;b&#39;}. We are going to use two iterators, one pointing into each sequence and emulating a nested for-loop. On each iteration we advance the iterator over the&amp;nbsp;{&#39;a&#39;, &#39;b&#39;}. Once the iterator advances past &#39;b&#39;, we reset it back to the beginning to point to &#39;a&#39; again and advance the iterator over {1, 2}.&lt;br /&gt;
&lt;br /&gt;
The analysis leads us to conclude that we will (a) need a tuple of iterators into the underlying ranges and (b) a tuple of references to the underlying ranges for resetting the iterators back to the beginning and comparing with the range ends. This demonstrates a weakness of Boost Ranges: our iterator is forced to keep references to the underlying ranges. Since the cartesian_range has two iterators (begin and end), this approach wastes memory. If the a range was a primitive (as in Alexandrescu&#39;s ranges), we could save on the extra references. Back to the code -- data members, constructors and equality check:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;std::tuple&amp;lt;typename boost::range_iterator&amp;lt;Rs&amp;gt;::type... &amp;gt; iters;
std::tuple&amp;lt;Rs&amp;amp;...&amp;gt; ranges;

cartesian_iterator() {}

// used to construct the begin iterator
cartesian_iterator(Rs&amp;amp;... rs) :
&amp;nbsp; &amp;nbsp; ranges(rs...),&amp;nbsp;iters(boost::begin(rs)...)&amp;nbsp;{}

// used to construct the end iterator
cartesian_iterator(Rs&amp;amp;... rs, int) :
&amp;nbsp; &amp;nbsp; ranges(rs...),&amp;nbsp;iters(boost::end(rs)...)&amp;nbsp;{}

// called by iterator_facade&#39;s impl of oprerator==
bool equal(cartesian_iterator const&amp;amp; other ) const {
&amp;nbsp; &amp;nbsp; return iters == other.iters;
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;div&gt;
With the easy parts are out of the way, let&#39;s tackle the iterator&#39;s increment functionality. Remember, we need to simulate the nested for loops but in a functional manner:&lt;/div&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;size_t N&amp;gt;
using const_int = std::integral_constant&amp;lt;size_t, N&amp;gt;;

// called by iterator_facade&#39;s impl of operator++
void increment() {
&amp;nbsp; &amp;nbsp; increment(const_int&amp;lt;sizeof...(Rs) - 1&amp;gt;());
}

// helpers
template &amp;lt;size_t N&amp;gt;
bool increment(const_int&amp;lt;N&amp;gt;) {
&amp;nbsp; &amp;nbsp; if( ++(std::get&amp;lt;N&amp;gt;(iters)) == boost::end(std::get&amp;lt;N&amp;gt;(ranges)) ) {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if( !increment(const_int&amp;lt;N-1&amp;gt;()) )
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return false;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; std::get&amp;lt;N&amp;gt;(iters) = boost::begin(std::get&amp;lt;N&amp;gt;(ranges));
&amp;nbsp; &amp;nbsp; }
&amp;nbsp; &amp;nbsp; return true;
}

// base case
bool increment(const_int&amp;lt;0&amp;gt;) {
&amp;nbsp; &amp;nbsp; return ++(std::get&amp;lt;0&amp;gt;(iters)) != boost::end(std::get&amp;lt;0&amp;gt;(ranges));
}
&lt;/pre&gt;
&lt;div&gt;
For any given iterator (starting with the last one), we increment it and if it reached the end, we recursively call ourselves to increment the previous iterator. If we are not at the very end, we reset the given iterator back to the beginning of the range.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;h2&gt;
Function application with a tuple&lt;/h2&gt;
&lt;/div&gt;
&lt;div&gt;
The last thing to do is to take care of the dereferencing. Before we proceed though, we need to sidestep and look at a problem that I think will often come up with variadics. I speak of calling a function with the arguments stored in a std::tuple. For example, if I have args of type std::tuple&amp;lt;int, char, double&amp;gt; and I want to call &quot;void foo(int, char, double)&quot; with args&#39; elements. It&#39;s trivial to do so in this case -- foo(std::get&amp;lt;0&amp;gt;(args),&amp;nbsp;std::get&amp;lt;1&amp;gt;(args),&amp;nbsp;std::get&amp;lt;2&amp;gt;(args)) -- but less so generically with the number of arguments not fixed. &lt;a href=&quot;http://stackoverflow.com/questions/7858817/unpacking-a-tuple-to-call-a-matching-function-pointer&quot;&gt;This&lt;/a&gt; StackOverflow thread&#39;s accepted answer provides the best way of doing so.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The main idea is for a tuple of size N to generate a sequence of type seq&amp;lt;0, 1, 2, ..., N-1&amp;gt;. Then call a helper function that will capture the integral sequence in its parameter pack and expand it into many calls to std::get&amp;lt;&amp;gt;:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;// the sequence type
template&amp;lt;size_t...&amp;gt;
struct seq { };

// meta-function to generate seq&amp;lt;0, 1, ..., N-1&amp;gt;
template&amp;lt;size_t N, size_t ...S&amp;gt;
struct gens : gens&amp;lt;N-1, N-1, S...&amp;gt; { };

template&amp;lt;size_t ...S&amp;gt;
struct gens&amp;lt;0, S...&amp;gt; {
&amp;nbsp; &amp;nbsp; typedef seq&amp;lt;S...&amp;gt; type;
};

// accepts a tuple and returns seq&amp;lt;0, 1, ..., N-1&amp;gt;
template &amp;lt;typename... Ts&amp;gt;
typename gens&amp;lt;sizeof...(Ts)&amp;gt;::type tuple_indices(std::tuple&amp;lt;Ts...&amp;gt; const&amp;amp;) {
&amp;nbsp; &amp;nbsp; return typename gens&amp;lt;sizeof...(Ts)&amp;gt;::type();
};

// helper that captures indices into a parameter pack and invokes f
template&amp;lt;typename F, typename Args, size_t ...Indices&amp;gt;
auto call_func(F&amp;amp;&amp;amp; f, Args&amp;amp;&amp;amp; args, seq&amp;lt;Indices...&amp;gt;) -&amp;gt; decltype(f(std::get&amp;lt;Indices&amp;gt;(args)...)) {
&amp;nbsp; &amp;nbsp; return f(std::get&amp;lt;Indices&amp;gt;(args)...);
}

// takes function f and tuple args and invokes f with args
template &amp;lt;typename F, typename Args&amp;gt;
auto invoke(F&amp;amp;&amp;amp; f, Args&amp;amp;&amp;amp; args) -&amp;gt; decltype(call_func(std::forward&amp;lt;F&amp;gt;(f), std::forward&amp;lt;Args&amp;gt;(args), tuple_indices(args))) {
&amp;nbsp; &amp;nbsp; return call_func(std::forward&amp;lt;F&amp;gt;(f), std::forward&amp;lt;Args&amp;gt;(args), tuple_indices(args));
}
&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I think this problem will come up so often that invoke() should become part of the Standard Library. But as you&#39;ll see in a moment, it is important to understand the technique, since invoke() will not always work for all problems of this type.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;h2&gt;
Back to Dereference&lt;/h2&gt;
&lt;/div&gt;
&lt;div&gt;
The dereference() function needs to construct a std::tuple out of the references returned by dereferencing each of the iterators. The problem here is subtly different from one solved by invoke() above. First, instead of a function (or callable), we are invoking a constructor (albeit this can by solved by using std::make_tuple). Second, our tuple does not contain values to be invoked with. Rather, each of those values (iters tuple contains iterators) needs to be dereferenced&amp;nbsp;first. Fortunately, the technique still applies:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;// invoked by iterator_facade&#39;s impl of operator*()
typename value_type&amp;lt;Rs...&amp;gt;::type dereference() const {
&amp;nbsp; &amp;nbsp; return dereference(tuple_indices(iters));
}

// helper
template &amp;lt;size_t... Indices&amp;gt;
typename value_type&amp;lt;Rs...&amp;gt;::type dereference(seq&amp;lt;Indices...&amp;gt;) const {
&amp;nbsp; &amp;nbsp; typedef typename value_type&amp;lt;Rs...&amp;gt;::type result_t;
&amp;nbsp; &amp;nbsp; return result_t(*std::get&amp;lt;Indices&amp;gt;(iters)...);
}
&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
We have now implemented all the necessary bits for a Forward Iterator.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;h2&gt;
Defining Boost.Range Adaptors&lt;/h2&gt;
&lt;/div&gt;
&lt;div&gt;
All that is left is to define xfiltered and xtransformed adaptors. It&#39;s a pretty simple process described &lt;a href=&quot;http://www.boost.org/doc/libs/1_51_0/libs/range/doc/html/range/reference/extending/method_3/method_3_2.html&quot;&gt;here&lt;/a&gt;. First, we define a polymorphic functor (expander) that will just call invoke() defined earlier. The rest of the code wraps the user passed function inside the expander and passes it on to filter and transform adaptors. Everything else is&amp;nbsp;just boilerplate specified by the Boost.Range&#39;s documentation:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;typename F&amp;gt;
struct expander {
&amp;nbsp; &amp;nbsp; F f;

&amp;nbsp; &amp;nbsp; template &amp;lt;typename... Args&amp;gt;
&amp;nbsp; &amp;nbsp; typename std::result_of&amp;lt;F(Args...)&amp;gt;::type operator()(std::tuple&amp;lt;Args...&amp;gt; tup) const {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return invoke(f, tup);
&amp;nbsp; &amp;nbsp; }
};

// --- xfiltered ---
template&amp;lt; class T &amp;gt;
struct xfilter_holder : boost::range_detail::holder&amp;lt;T&amp;gt; {
&amp;nbsp; &amp;nbsp; xfilter_holder( T r ) : boost::range_detail::holder&amp;lt;T&amp;gt;(r) { }
};

template&amp;lt; class InputRng, class Pred &amp;gt;
boost::filtered_range&amp;lt;expander&amp;lt;Pred&amp;gt;, const InputRng&amp;gt;
operator|( const InputRng&amp;amp; r, const xfilter_holder&amp;lt;Pred&amp;gt;&amp;amp; f ) {
&amp;nbsp; &amp;nbsp; return boost::filtered_range&amp;lt;expander&amp;lt;Pred&amp;gt;, const InputRng&amp;gt;( expander&amp;lt;Pred&amp;gt;{f.val}, r );&amp;nbsp;
}

const boost::range_detail::forwarder&amp;lt;xfilter_holder&amp;gt; xfiltered = boost::range_detail::forwarder&amp;lt;xfilter_holder&amp;gt;();

// --- xtransformed---
template&amp;lt; class T &amp;gt;
struct xtransform_holder : boost::range_detail::holder&amp;lt;T&amp;gt; {
&amp;nbsp; &amp;nbsp; xtransform_holder( T r ) : boost::range_detail::holder&amp;lt;T&amp;gt;(r) { }
};

template&amp;lt; class InputRng, class F &amp;gt;
boost::transformed_range&amp;lt;expander&amp;lt;F&amp;gt;, const InputRng&amp;gt;
operator|( const InputRng&amp;amp; r, const xtransform_holder&amp;lt;F&amp;gt;&amp;amp; f ) {
&amp;nbsp; &amp;nbsp; return boost::transformed_range&amp;lt;expander&amp;lt;F&amp;gt;, const InputRng&amp;gt;( expander&amp;lt;F&amp;gt;{f.val}, r );
}

const boost::range_detail::forwarder&amp;lt;xtransform_holder&amp;gt; xtransformed = boost::range_detail::forwarder&amp;lt;xtransform_holder&amp;gt;();&lt;/pre&gt;
&lt;div&gt;
&lt;h2&gt;
Conclusion&lt;/h2&gt;
&lt;/div&gt;
&lt;div&gt;
Boost.Range provides useful blocks that can be put together to express set-builder notation of one variable. Defining a cartesian_range allows for generalizing the solution to any number of variables. We also saw that the leaky nature of Boost Ranges make it awkward to define some types of ranges/iterators. Variadic templates and std::tuple are great additions to C++ but the Standard Library could benefit from an invoke() function.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://dev-perspective.blogspot.com/feeds/6826180693263620772/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dev-perspective.blogspot.com/2012/10/on-list-comprehension-in-c.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/6826180693263620772'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/6826180693263620772'/><link rel='alternate' type='text/html' href='http://dev-perspective.blogspot.com/2012/10/on-list-comprehension-in-c.html' title='On List Comprehension in C++'/><author><name>Eugene</name><uri>http://www.blogger.com/profile/15405098005234713619</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7098284592115366563.post-402001686521747232</id><published>2012-09-07T13:25:00.001-07:00</published><updated>2013-07-27T10:39:32.000-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Boost"/><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="C++11"/><title type='text'>Iterating over a text file</title><content type='html'>It&#39;s a simple task -- you want iterate over all the lines in a file and perform an action on each one. In Python it&#39;s as simple as:&lt;br /&gt;
&lt;pre class=&quot;brush: python&quot;&gt;for line in open(&quot;somefile.txt&quot;):
&amp;nbsp; &amp;nbsp; print line
&lt;/pre&gt;
How about C++11. How hard can it be? &lt;a href=&quot;http://stackoverflow.com/questions/2291802/is-there-a-c-iterator-that-can-iterate-over-a-file-line-by-line&quot;&gt;This&lt;/a&gt; stackoverflow post gives us a starting point. We first define an iterator:&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;struct line_t : std::string {
&amp;nbsp; &amp;nbsp; &amp;nbsp;friend std::istream &amp;amp; operator&amp;gt;&amp;gt;(std::istream&amp;amp; is, line_t&amp;amp; line) {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return std::getline(is, line);
&amp;nbsp; &amp;nbsp; &amp;nbsp;}
};
typedef std::istream_iterator&amp;lt;line_t&amp;gt; line_iterator;
&lt;/pre&gt;
&lt;a href=&quot;http://www.boost.org/doc/libs/1_51_0/libs/range/doc/html/index.html&quot;&gt;Boost.Range&lt;/a&gt;&amp;nbsp;packages a pair of begin/end iterators into a &lt;i&gt;range&lt;/i&gt;&amp;nbsp;which makes the code more elegant. It defines all those algorithms found in std namespace in terms of ranges. So we&#39;ll give ranges a try and hope it improves our style. Since std::pair of iterators is a valid Boost.Range range, let&#39;s define a line_range in terms of that and also a helper function to construct the range:&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;typedef std::pair&amp;lt;line_iterator, line_iterator&amp;gt; line_range;

line_range lines(std::ifstream&amp;amp; is) {
&amp;nbsp; &amp;nbsp; return line_range(line_iterator(is), line_iterator());
}
&lt;/pre&gt;
Now we can use Boost.Range&#39;s for_each to iterate over a file:&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;std::ifstream file(&quot;somefile.txt&quot;);
boost::for_each(lines(file), [](std::string const&amp;amp; line) {
&amp;nbsp; &amp;nbsp; std::cout &amp;lt;&amp;lt; line &amp;lt;&amp;lt; std::endl;
});
&lt;/pre&gt;
Not bad. Not counting the very last line, it&#39;s 3 lines of code. One more than Python. Let&#39;s see if we can get it down to two lines by constructing the ifstream object as a temporary:
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;boost::for_each(lines(std::ifstream(&quot;somefile.txt&quot;)), [](std::string const&amp;amp; line) {
&amp;nbsp; &amp;nbsp; std::cout &amp;lt;&amp;lt; line &amp;lt;&amp;lt; std::endl;
});
&lt;/pre&gt;
&lt;pre&gt;g++ -std=c++0x iter.cpp
iter.cpp: In function ‘int main()’:
iter.cpp:97:54: error: invalid initialization of non-const reference of type ‘std::ifstream&amp;amp; {aka std::basic_ifstream&amp;lt;char&amp;gt;&amp;amp;}’ from an rvalue of type ‘std::ifstream {aka std::basic_ifstream&amp;lt;char&amp;gt;}’
iter.cpp:82:12: error: in passing argument 1 of ‘line_range lines(std::ifstream&amp;amp;)’
&lt;/pre&gt;
That doesn&#39;t work. Of course -- passing a temporary into a function that takes a non-const reference will not work. Unfortunately we can&#39;t change it to a const reference since istream_iterator&#39;s constructor takes a non-const reference. Fortunately we can deal with this situation by taking it as an rvalue reference:&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;line_range lines(std::ifstream&amp;amp;&amp;amp; is) {
&amp;nbsp; &amp;nbsp; return line_range(line_iterator(is), line_iterator());
}
&lt;/pre&gt;
This will happily compile and work but we just broke the previous usage. That is because an rvalue reference won&#39;t bind to an lvalue. We can do two things to solve this problem. First is to provide two overloads:&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;line_range lines(std::ifstream&amp;amp; is) {
&amp;nbsp; &amp;nbsp; return line_range(line_iterator(is), line_iterator());
}

line_range lines(std::ifstream&amp;amp;&amp;amp; is) {
&amp;nbsp; &amp;nbsp; return lines(is);
}
&lt;/pre&gt;
The second overload ends up calling the first one because an rvalue reference is itself an lvalue! See the&amp;nbsp;&lt;a href=&quot;http://thbecker.net/articles/rvalue_references/section_01.html&quot;&gt;tutorial by Thomas Becker&lt;/a&gt; to learn everything you&#39;ll ever need about rvalue references. The other way is to use the mechanism employed by std::forward:&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;typename S&amp;gt;
line_range lines(S&amp;amp;&amp;amp; is) {
&amp;nbsp; &amp;nbsp; return line_range(line_iterator(is), line_iterator());
}
&lt;/pre&gt;
A call with lvalue will bind S to std::ifstream&amp;amp; and with &amp;amp;&amp;amp; will collapse to just std::ifstream&amp;amp;. A call with rvalue will bind S to std::ifstream and the whole thing will be std::ifstream&amp;amp;&amp;amp;. Again, see Becker&#39;s &lt;a href=&quot;http://thbecker.net/articles/rvalue_references/section_08.html&quot;&gt;Section 8&lt;/a&gt; for more detail.&lt;br /&gt;
Presto! We got two perfectly good ways to make it work with temporaries or not.


&lt;br /&gt;
&lt;h2&gt;
Room for Improvement: Using range-based-for&lt;/h2&gt;
As much as I love lambdas and functional programming, there is a lot to be said for a good old for loop. And with C++11 we have the new range-based-for (aka foreach). I&#39;d rather write this:

&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;for( auto&amp;amp; line: lines(std::ifstream(&quot;somefile.txt&quot;)) )
&amp;nbsp; &amp;nbsp; std::cout &amp;lt;&amp;lt; line &amp;lt;&amp;lt; std::endl;
&lt;/pre&gt;
In order for the range-based-for to work we must expose begin/end iterators via one of two ways. Either our line_range needs to have begin() and end() methods (just like STL containers) or we need to have free functions with same names such that ADL can pick them up. Since Boost.Range defines such free functions (boost::begin() and boost::end()), all we need to do is dump them into our namespace:

&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;using boost::begin;
using boost::end;

std::ifstream file(&quot;somefile.txt&quot;);
for( auto&amp;amp; line: lines(file) )
&amp;nbsp; &amp;nbsp; std::cout &amp;lt;&amp;lt; line &amp;lt;&amp;lt; std::endl;
&lt;/pre&gt;
This works great but unfortunately this does not (although it compiles):&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;for( auto&amp;amp; line: lines(std::ifstream(&quot;somefile.txt&quot;)) )
&amp;nbsp; &amp;nbsp; std::cout &amp;lt;&amp;lt; line &amp;lt;&amp;lt; std::endl;
&lt;/pre&gt;
The reason being is that the compiler transforms this loop&amp;nbsp;[stmt.ranged/1]&amp;nbsp;into:

&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;auto&amp;amp;&amp;amp; __range = lines(std::ifstream(&quot;somefile.txt&quot;));
// regular for loop using iterators returned by begin(__range) and end(__range)
&lt;/pre&gt;
lines() returns the instance of line_range by value but its lifetime is extended to that of a the __range reference. However the lifetime of std::ifstream temporary is &lt;i&gt;not&lt;/i&gt; extended! It is destroyed before the loop is even started. It&#39;s a problem that didn&#39;t exist when we were using boost::for_each since the whole iteration was all one statement. See&amp;nbsp;[class.temporary/5] for details.&lt;br /&gt;
How should we fix it? Since the line_range temporary lives on for the duration of the loop, we need to move the instance of std::ifstream &lt;i&gt;into&lt;/i&gt; it. For the cases where std::ifstream is an lvalue rather than a temporary, we can just store a reference to it. Let&#39;s get started.

&lt;br /&gt;
&lt;br /&gt;
Start off by redefining line_range as a class, ditching the std::pair of iterators:

&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;typename T&amp;gt;
class line_range {
&amp;nbsp; &amp;nbsp; T istr;
public:
&amp;nbsp; &amp;nbsp; line_range(T&amp;amp;&amp;amp; is) : istr(std::forward&amp;lt;T&amp;gt;(is)) {}
&amp;nbsp; &amp;nbsp; line_iterator begin() { return line_iterator(istr); }
&amp;nbsp; &amp;nbsp; line_iterator end() { return line_iterator(); }
};
&lt;/pre&gt;
&lt;br /&gt;
We need to rig this up so that T=std::ifstream if a temporary is used and T=std::ifstream&amp;amp; otherwise. Well, we know how to this! You did read&amp;nbsp;Becker&#39;s&amp;nbsp;&lt;a href=&quot;http://thbecker.net/articles/rvalue_references/section_08.html&quot;&gt;Section 8&lt;/a&gt;, didn&#39;t you?!

&lt;br /&gt;
It&#39;s as simple as (albeit syntax is not simple):

&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;typename S&amp;gt;
auto lines(S&amp;amp;&amp;amp; is) -&amp;gt; decltype(line_range&amp;lt;S&amp;gt;(std::forward&amp;lt;S&amp;gt;(is))) {
&amp;nbsp; &amp;nbsp; return line_range&amp;lt;S&amp;gt;(std::forward&amp;lt;S&amp;gt;(is));
}
&lt;/pre&gt;
It&#39;s an example of the Perfect Forwarding problem -- we just forward rvalueness/lvalueness through to the line_range and end up either moving the object or storing the reference to it.&amp;nbsp;As a very last step, we have to slightly modify the line_range to once again&amp;nbsp;accommodate&amp;nbsp;Boost.Range. Complete code is shown below:&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;#include &amp;lt;iostream&amp;gt;
#include &amp;lt;fstream&amp;gt;
#include &amp;lt;boost/range/algorithm/for_each.hpp&amp;gt;

struct line_t : std::string {
&amp;nbsp; &amp;nbsp; &amp;nbsp;friend std::istream &amp;amp; operator&amp;gt;&amp;gt;(std::istream&amp;amp; is, line_t&amp;amp; line) {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return std::getline(is, line);
&amp;nbsp; &amp;nbsp; &amp;nbsp;}
};

typedef std::istream_iterator&amp;lt;line_t&amp;gt; line_iterator;

template &amp;lt;typename T&amp;gt;
class line_range {
&amp;nbsp; &amp;nbsp; T istr;
&amp;nbsp; &amp;nbsp; line_iterator b;

public:
&amp;nbsp; &amp;nbsp; typedef line_iterator iterator;
&amp;nbsp; &amp;nbsp; typedef line_iterator const_iterator;

&amp;nbsp; &amp;nbsp; line_range(T&amp;amp;&amp;amp; is) :
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; istr(std::forward&amp;lt;T&amp;gt;(is)),
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; b(istr)
&amp;nbsp; &amp;nbsp; {}

&amp;nbsp; &amp;nbsp; line_iterator begin() const { return b; }
&amp;nbsp; &amp;nbsp; line_iterator end() const { return line_iterator(); }
};

template &amp;lt;typename S&amp;gt;
auto lines(S&amp;amp;&amp;amp; is) -&amp;gt; decltype(line_range&amp;lt;S&amp;gt;(std::forward&amp;lt;S&amp;gt;(is))) {
&amp;nbsp; &amp;nbsp; return line_range&amp;lt;S&amp;gt;(std::forward&amp;lt;S&amp;gt;(is));
}

int main()
{
&amp;nbsp; &amp;nbsp; std::ifstream file(&quot;somefile.txt&quot;);
&amp;nbsp; &amp;nbsp; for( auto&amp;amp; line: lines(file) )
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; std::cout &amp;lt;&amp;lt; line &amp;lt;&amp;lt; std::endl;

&amp;nbsp; &amp;nbsp; for( auto&amp;amp; line: lines(std::ifstream(&quot;somefile.txt&quot;)) )
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; std::cout &amp;lt;&amp;lt; line &amp;lt;&amp;lt; std::endl;

&amp;nbsp; &amp;nbsp; std::ifstream file2(&quot;somefile.txt&quot;);
&amp;nbsp; &amp;nbsp; boost::for_each(lines(file2), [](std::string const&amp;amp; line) {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; std::cout &amp;lt;&amp;lt; line &amp;lt;&amp;lt; std::endl;
&amp;nbsp; &amp;nbsp; });

&amp;nbsp; &amp;nbsp; boost::for_each(lines(std::ifstream(&quot;somefile.txt&quot;)), [](std::string const&amp;amp; line) {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; std::cout &amp;lt;&amp;lt; line &amp;lt;&amp;lt; std::endl;
&amp;nbsp; &amp;nbsp; });

&amp;nbsp; &amp;nbsp; return 0;
}
&lt;/pre&gt;
</content><link rel='replies' type='application/atom+xml' href='http://dev-perspective.blogspot.com/feeds/402001686521747232/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dev-perspective.blogspot.com/2012/09/iterating-over-text-file.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/402001686521747232'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/402001686521747232'/><link rel='alternate' type='text/html' href='http://dev-perspective.blogspot.com/2012/09/iterating-over-text-file.html' title='Iterating over a text file'/><author><name>Eugene</name><uri>http://www.blogger.com/profile/15405098005234713619</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7098284592115366563.post-6735578558743136582</id><published>2012-08-04T14:39:00.000-07:00</published><updated>2012-08-04T14:39:16.727-07:00</updated><title type='text'>Thoughts on Steve Jobs Biography</title><content type='html'>I recently finished reading biography of Steve Jobs by Walter Isaacson. It&#39;s a great book that shows Jobs not only from his side but also as perceived by his friends and enemies. After reading the book, I can certainly say that Steve Jobs was a complicated person. I can&#39;t say that I can admire him but there are definitely traits in him that appeal to me.&lt;br /&gt;
&lt;br /&gt;
I consider myself a geek. I like technology. I like taking it apart, whether it&#39;s upgrading a part in my computer or studying the source of an open source project. By this account, Apple products should not appeal to me.&amp;nbsp;After all, you can&#39;t even replace the battery in most of its devices. And yet I own an iPhone, an iPod and MacBook Air (I do also have a Linux desktop). I have these Apple devices because I love their design. I love how they look -- the body, the interface, the little click the magnetic plug of the charger makes as it latches onto my MacBook. When I talk to other geeks about Apple, some mock me for&amp;nbsp;indulging&amp;nbsp;in this &quot;trivial&quot; stuff. They think that people should not care about this fluff and should only care about how many GHz or GB the machine has. Or at least geeks shouldn&#39;t. They say that Apple is not a technology company, it&#39;s an industrial design company, making it sound like an insult. And yet many of these geeks admire cars like Mercedes, BMW or Ferrari. And while they appreciate the horsepower of the engine or quality workmanship, they love to talk and adore the car&#39;s design. A car is a piece of technology. Why is it ok for geeks to admire its design but not the design of a notebook or a phone?&lt;br /&gt;
&lt;br /&gt;
And so I admire Steve Jobs for getting it that hi-tech should be beautiful and not just functional. And I also admire his desire to have everything work by having everything be integrated. Who doesn&#39;t like it when &quot;it just works&quot;. But what I don&#39;t agree with is his assertion that it can only be achieved with a closed system. In fact he demonstrated that it doesn&#39;t have to be. Because Jobs would insist that Apple focus on only a few things at a time, they avoided making anything that would not be &quot;absolutely great&quot;. For example, under his watch Apple was not in the printer business. And yet printers work pretty well with Macs. Third party printers connect via open interfaces (USB, LPD, IPP) and work just fine with PCs and Macs (unfortunately not Linux). Another example is iPhone. When it launched, Apple did not the capacity do its own maps. So while it developed the app, it used Google&#39;s data to power it. That was only possible because Google&#39;s maps &lt;i&gt;were&lt;/i&gt; open.&lt;br /&gt;
&lt;br /&gt;
So I hope many companies will copy Apple and pay more attention to design, simplicity and focus, but not embrace its close-system philosophy. I hope companies will embrace standards, open formats and open source. But I hope they will do so without sacrificing the ease of use and the &quot;just works&quot; philosophy. I truly believe they are not mutually exclusive.</content><link rel='replies' type='application/atom+xml' href='http://dev-perspective.blogspot.com/feeds/6735578558743136582/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dev-perspective.blogspot.com/2012/08/thoughts-on-steve-jobs-biography.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/6735578558743136582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/6735578558743136582'/><link rel='alternate' type='text/html' href='http://dev-perspective.blogspot.com/2012/08/thoughts-on-steve-jobs-biography.html' title='Thoughts on Steve Jobs Biography'/><author><name>Eugene</name><uri>http://www.blogger.com/profile/15405098005234713619</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7098284592115366563.post-8973001122185779543</id><published>2012-07-22T09:47:00.000-07:00</published><updated>2012-07-22T09:47:43.970-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Boost"/><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="C++11"/><category scheme="http://www.blogger.com/atom/ns#" term="metaprogramming"/><category scheme="http://www.blogger.com/atom/ns#" term="TBB"/><title type='text'>More fun with Intel TBB and Boost.Proto (and Boost.Fusion)</title><content type='html'>In my last &lt;a href=&quot;http://dev-perspective.blogspot.com/2012/07/fun-with-intel-tbb-and-boostproto.html&quot;&gt;post&lt;/a&gt;, we developed an EDSL for specifying TBB Flow Graph structure with the help of Boost.Proto. Instead of writing a series of tbb::flow::make_edge calls, we can use a little language to help us be more declarative. In the process, however, we lost some of the runtime&amp;nbsp;efficiency. Instead of just invoking make_edge() a number of times, our solution uses loops and temporary data structures (e.g. std::set) which introduce runtime overhead. In this post, we will look at how to modify what we did last time to create a meta-program that will enable us to remove the&amp;nbsp;unnecessary runtime overhead.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;h2&gt;
Boost.Fusion&lt;/h2&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;a href=&quot;http://www.boost.org/libs/fusion/&quot; style=&quot;background-color: white;&quot;&gt;Fusion&lt;/a&gt;&lt;span style=&quot;background-color: white;&quot;&gt; library sits somewhere between &lt;/span&gt;&lt;a href=&quot;http://www.boost.org/libs/mpl/&quot; style=&quot;background-color: white;&quot;&gt;Boost.MPL&lt;/a&gt;&lt;span style=&quot;background-color: white;&quot;&gt; and STL. Like MPL, it provides&amp;nbsp;heterogeneous&amp;nbsp;data structures but&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;unlike MPL &lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;it is able to operate at runtime. It also is a great tool for certain meta-programming tasks. For example, suppose we wanted to generate code that would invoke foo() multiple times, each with a different value (and maybe type). With Fusion, it is as easy as putting those values into a fusion::vector and then calling fusion::for_each() with the vector and a polymorphic functor:&lt;/span&gt;&lt;/div&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;void foo(int);
void foo(double);

struct call_foo {
    template &amp;lt;typename T&amp;gt;
    void operator()(T x) const {
        foo(x);
    }
};

int main() {
    boost::fusion::vector&amp;lt;int, double, int&amp;gt; v(1, 2.3, 4);
    boost::fusion::for_each(v, call_foo());
    return 0;
}
&lt;/pre&gt;
&lt;br /&gt;
Once the program is compiled with optimizations enabled, all that remains are just foo() invocations (I ran the output generated via -s flag through c++filt to demangle the names):&lt;br /&gt;
&lt;pre class=&quot;brush: plain&quot;&gt;main:                          # @main
    .cfi_startproc
# BB#0:
    pushq %rax
.Ltmp1:
    .cfi_def_cfa_offset 16
    movl $1, %edi
    callq foo(int)
    movsd .LCPI0_0(%rip), %xmm0
    callq foo(double)
    movl $4, %edi
    callq foo(int)
    xorl %eax, %eax
    popq %rdx
    ret
&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Since what we are trying to do is generate a bunch of make_edge() calls, this seems like exactly what we need.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;h2&gt;
Putting it all together&lt;/h2&gt;
The basic idea is very simple. Replace the use of std::set with boost::fusion::vector when keeping track of senders and receivers in a compound node. We begin by re-defining compound_node to bundle up two fusion vectors. I replaced the use of std::tuple with a struct to make the code more readable and also added a utility function to make the construction easier:&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;typename Senders, typename Receivers&amp;gt;
struct compound_node {
    typedef Senders senders_t;
    typedef Receivers receivers_t;

    senders_t senders;
    receivers_t receivers;
};

template &amp;lt;typename S, typename R&amp;gt;
compound_node&amp;lt;S, R&amp;gt; mk_compound_node(S s, R r) {
    return compound_node&amp;lt;S, R&amp;gt;{s, r};
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
Now it&#39;s time to modify the make_compound_node transform that is invoked by Proto everytime it meets a terminal:&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;struct make_compound_node : proto::callable {
    typedef compound_node&amp;lt;
        fusion::vector&amp;lt;flow::sender&amp;lt;flow::continue_msg&amp;gt; *&amp;gt;,
        fusion::vector&amp;lt;flow::receiver&amp;lt;flow::continue_msg&amp;gt; *&amp;gt;
    &amp;gt; result_type;

    result_type operator()(flow::sender&amp;lt;flow::continue_msg&amp;gt;&amp;amp; s, flow::receiver&amp;lt;flow::continue_msg&amp;gt;&amp;amp; r) {
        return mk_compound_node(
            fusion::vector&amp;lt;flow::sender&amp;lt;flow::continue_msg&amp;gt; *&amp;gt;(&amp;amp;s),
            fusion::vector&amp;lt;flow::receiver&amp;lt;flow::continue_msg&amp;gt; *&amp;gt;(&amp;amp;r)
        );
    }
};
&lt;/pre&gt;
&lt;br /&gt;
Next up is the join transform that is applied to process the + operator. Recall that all it has to do is create a new compound node by joining the senders and receivers of the left and right hand sides. To join two Fusion vectors, we use fusion::join function.&amp;nbsp;Unfortunately, it returns not a new vector but a view which contains references to the original sequences it was asked to join. Because we pass everything by value and have tons of temporaries, this is a recipe for disaster. So we force Fusion to create a new vector by passing the result of join to fusion::as_vector. The messy part turns out to be the return type. Remember, Proto transforms have to comply with &lt;a href=&quot;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1454.html&quot;&gt;(TR1/C++11) result_of protocol&lt;/a&gt;. While previously we got away by using the simple method of typedef&#39;ing a result_type, this time our return type depends on the types of&amp;nbsp;arguments. We have to define a meta-function by specializing the result&amp;lt;Sig&amp;gt; struct. Luckily, Fusion library also supports a uniform way of computing result types of its functions (albeit slightly different from the standard approach). All of its functions have a meta-function with the same name in the fusion::result_of namespace.&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;struct join : proto::callable {
&amp;nbsp; &amp;nbsp; template &amp;lt;typename Sig&amp;gt;
&amp;nbsp; &amp;nbsp; struct result;

&amp;nbsp; &amp;nbsp; template &amp;lt;typename This, typename LeftNode, typename RightNode&amp;gt;
&amp;nbsp; &amp;nbsp; struct result&amp;lt;This(LeftNode, RightNode)&amp;gt; {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; typedef typename LeftNode::senders_t left_senders_t;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; typedef typename LeftNode::receivers_t left_receivers_t;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; typedef typename RightNode::senders_t right_senders_t;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; typedef typename RightNode::receivers_t right_receivers_t;

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; typedef compound_node&amp;lt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; typename fusion::result_of::as_vector&amp;lt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; typename fusion::result_of::join&amp;lt;left_senders_t const, right_senders_t const&amp;gt;::type
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;gt;::type,
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; typename fusion::result_of::as_vector&amp;lt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; typename fusion::result_of::join&amp;lt;left_receivers_t const, right_receivers_t const&amp;gt;::type
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;gt;::type
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;gt; type;
&amp;nbsp; &amp;nbsp; };

&amp;nbsp; &amp;nbsp; template &amp;lt;typename LeftNode, typename RightNode&amp;gt;
&amp;nbsp; &amp;nbsp; typename result&amp;lt;join(LeftNode, RightNode)&amp;gt;::type operator()(LeftNode left, RightNode right) const {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return mk_compound_node(
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fusion::as_vector(fusion::join(left.senders, right.senders)),
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fusion::as_vector(fusion::join(left.receivers, right.receivers))
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; );
&amp;nbsp; &amp;nbsp; };
};
&lt;/pre&gt;
&lt;br /&gt;
&lt;div&gt;
Finally we get to the meat of the problem -- implementing splice transform where actual make_edge calls are made. Just like in the join transform above, we need to adhere to result_of protocol using struct specialization. We also need to execute the double for loop: the outer loop iterates over the left-hand&#39;s senders and the inner one over the right-hand receivers. But of course we&#39;ll use fusion::for_each() twice to do the looping. We are lucky that the fusion::vectors contain&amp;nbsp;homogeneous types -- they are all either flow::sender&amp;lt;continue_msg&amp;gt; or flow::receiver&amp;lt;continue_msg&amp;gt;. This makes it possible to use C++11 lambdas and keep everything in one place.&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;struct splice : proto::callable {
&amp;nbsp; &amp;nbsp; template &amp;lt;typename Sig&amp;gt;
&amp;nbsp; &amp;nbsp; struct result;

&amp;nbsp; &amp;nbsp; template &amp;lt;typename This, typename LeftNode, typename RightNode&amp;gt;
&amp;nbsp; &amp;nbsp; struct result&amp;lt;This(LeftNode, RightNode)&amp;gt; {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; typedef compound_node&amp;lt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; typename RightNode::senders_t,
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; typename LeftNode::receivers_t
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;gt; type;
&amp;nbsp; &amp;nbsp; };

&amp;nbsp; &amp;nbsp; template &amp;lt;typename LeftNode, typename RightNode&amp;gt;
&amp;nbsp; &amp;nbsp; typename result&amp;lt;splice(LeftNode, RightNode)&amp;gt;::type operator()(LeftNode left, RightNode right) const {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fusion::for_each(left.senders, [&amp;amp;](flow::sender&amp;lt;flow::continue_msg&amp;gt;* s) {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fusion::for_each(right.receivers, [=](flow::receiver&amp;lt;flow::continue_msg&amp;gt;* r) {
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; flow::make_edge(*s, *r);
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; });
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; });

&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return mk_compound_node(right.senders, left.receivers);
&amp;nbsp; &amp;nbsp; }
};
&lt;/pre&gt;
&lt;br /&gt;
Note that no changes were necessary to the grammar nor, of course, main(). To verify that we reached our goal, let&#39;s check out the&amp;nbsp;disassembly. Since flow::make_edge is inline function, I temporarily declared a make_edge() in the global namespace with the matching signature and used that instead. And voilà:&lt;br /&gt;
&lt;pre class=&quot;brush: plain&quot;&gt;&amp;nbsp; &amp;nbsp; leaq &amp;nbsp; &amp;nbsp;560(%rsp), %rsi
&amp;nbsp; &amp;nbsp; leaq &amp;nbsp; &amp;nbsp;344(%rsp), %rdi
.LEHB53:
&amp;nbsp; &amp;nbsp; call &amp;nbsp; &amp;nbsp;make_edge(tbb::flow::interface6::sender&amp;lt;tbb::flow::interface6::continue_msg&amp;gt;&amp;amp;, tbb::flow::interface6::receiver&amp;lt;tbb::flow::interface6::continue_msg&amp;gt;&amp;amp;)
&amp;nbsp; &amp;nbsp; leaq &amp;nbsp; &amp;nbsp;816(%rsp), %rsi
&amp;nbsp; &amp;nbsp; leaq &amp;nbsp; &amp;nbsp;600(%rsp), %rdi
&amp;nbsp; &amp;nbsp; call &amp;nbsp; &amp;nbsp;make_edge(tbb::flow::interface6::sender&amp;lt;tbb::flow::interface6::continue_msg&amp;gt;&amp;amp;, tbb::flow::interface6::receiver&amp;lt;tbb::flow::interface6::continue_msg&amp;gt;&amp;amp;)
&amp;nbsp; &amp;nbsp; leaq &amp;nbsp; &amp;nbsp;1072(%rsp), %rsi
&amp;nbsp; &amp;nbsp; leaq &amp;nbsp; &amp;nbsp;88(%rsp), %rdi
&amp;nbsp; &amp;nbsp; call &amp;nbsp; &amp;nbsp;make_edge(tbb::flow::interface6::sender&amp;lt;tbb::flow::interface6::continue_msg&amp;gt;&amp;amp;, tbb::flow::interface6::receiver&amp;lt;tbb::flow::interface6::continue_msg&amp;gt;&amp;amp;)
&amp;nbsp; &amp;nbsp; leaq &amp;nbsp; &amp;nbsp;560(%rsp), %rsi
&amp;nbsp; &amp;nbsp; leaq &amp;nbsp; &amp;nbsp;88(%rsp), %rdi
&amp;nbsp; &amp;nbsp; call &amp;nbsp; &amp;nbsp;make_edge(tbb::flow::interface6::sender&amp;lt;tbb::flow::interface6::continue_msg&amp;gt;&amp;amp;, tbb::flow::interface6::receiver&amp;lt;tbb::flow::interface6::continue_msg&amp;gt;&amp;amp;)
&amp;nbsp; &amp;nbsp; leaq &amp;nbsp; &amp;nbsp;48(%rsp), %rsi
&amp;nbsp; &amp;nbsp; leaq &amp;nbsp; &amp;nbsp;1336(%rsp), %rdi
&amp;nbsp; &amp;nbsp; call &amp;nbsp; &amp;nbsp;make_edge(tbb::flow::interface6::sender&amp;lt;tbb::flow::interface6::continue_msg&amp;gt;&amp;amp;, tbb::flow::interface6::receiver&amp;lt;tbb::flow::interface6::continue_msg&amp;gt;&amp;amp;)
&amp;nbsp; &amp;nbsp; leaq &amp;nbsp; &amp;nbsp;304(%rsp), %rsi
&amp;nbsp; &amp;nbsp; leaq &amp;nbsp; &amp;nbsp;1336(%rsp), %rdi
&amp;nbsp; &amp;nbsp; call &amp;nbsp; &amp;nbsp;make_edge(tbb::flow::interface6::sender&amp;lt;tbb::flow::interface6::continue_msg&amp;gt;&amp;amp;, tbb::flow::interface6::receiver&amp;lt;tbb::flow::interface6::continue_msg&amp;gt;&amp;amp;)
&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev-perspective.blogspot.com/feeds/8973001122185779543/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dev-perspective.blogspot.com/2012/07/more-fun-with-intel-tbb-and-boostproto.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/8973001122185779543'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/8973001122185779543'/><link rel='alternate' type='text/html' href='http://dev-perspective.blogspot.com/2012/07/more-fun-with-intel-tbb-and-boostproto.html' title='More fun with Intel TBB and Boost.Proto (and Boost.Fusion)'/><author><name>Eugene</name><uri>http://www.blogger.com/profile/15405098005234713619</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7098284592115366563.post-6478579165225151476</id><published>2012-07-14T10:06:00.001-07:00</published><updated>2012-07-20T10:07:08.293-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Boost"/><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="C++11"/><category scheme="http://www.blogger.com/atom/ns#" term="TBB"/><title type='text'>Fun with Intel TBB and Boost.Proto</title><content type='html'>&lt;h2&gt;






















Intel Threading Building Blocks&lt;/h2&gt;
As the hardware engineers cram more and more cores into the processors, software engineers are left to ponder about how to best exploit these new capabilities. Intel offers an open source C++ library they call Threading Building Blocks (TBB). Akin to competing solutions (OpenMP, GCD, PPL), the library allows the developer to break up the computation into bite size pieces called tasks. A task also has a successor (or parent) task which makes it possible to express a relationship describing who should run before whom. The library runtime then takes care of scheduling the tasks onto the physical threads. It is, however, error prone and&amp;nbsp;inconvenient&amp;nbsp;to program using the tasks. Thankfully, much of the programming can be expressed via higher level abstractions (especially those involving fork-join parallelism). For example, parallel_for function allows for using multiple threads to execute the iterations of the loop. Another example is parallel_pipeline function which allows for expressing pipes-and-filters kind of parallelism.&lt;br /&gt;
&lt;br /&gt;
TBB also has a facility called a Flow Graph. Designed for those situations when it is best to express the concurrency as a directed graph of&amp;nbsp;dependencies between message emitting nodes, Flow Graph stands almost like a separate library within the library. Let&#39;s take a look at an &lt;a href=&quot;http://threadingbuildingblocks.org/docs/help/reference/flow_graph/dependency_flow_graph_example.htm&quot;&gt;example&lt;/a&gt; from TBB&#39;s online reference. In this example, every node will print its name after it receives a completion message from the node that it depends on. Here&#39;s the dependency graph:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUMlomdRN5GbbnnXFvHrFOR-Nf-Xy8QoZJaqh8gaoLdMki7QRMIoSGKzWKqurIe0zTIxiOKZNp17aWT1Zapx0lVhQFs_Qw3cI89VzdJA8GYkGnGGn8IL2RcFWFvvrsz5ZDhsaohiZ4MrjI/s1600/dep_graph.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUMlomdRN5GbbnnXFvHrFOR-Nf-Xy8QoZJaqh8gaoLdMki7QRMIoSGKzWKqurIe0zTIxiOKZNp17aWT1Zapx0lVhQFs_Qw3cI89VzdJA8GYkGnGGn8IL2RcFWFvvrsz5ZDhsaohiZ4MrjI/s320/dep_graph.jpg&quot; width=&quot;194&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
And the corresponding code:&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;#include &amp;lt;cstdio&amp;gt;
#include &quot;tbb/flow_graph.h&quot;

using namespace tbb::flow;

struct body {
    std::string my_name;
    body( const char *name ) : my_name(name) {}
    void operator()( continue_msg ) const {
        std::printf(&quot;%s\n&quot;, my_name.c_str());
    }
};

int main() {
    graph g;

    broadcast_node&amp;lt; continue_msg &amp;gt; start;
    continue_node&amp;lt;continue_msg&amp;gt; a( g, body(&quot;A&quot;));
    continue_node&amp;lt;continue_msg&amp;gt; b( g, body(&quot;B&quot;));
    continue_node&amp;lt;continue_msg&amp;gt; c( g, body(&quot;C&quot;));
    continue_node&amp;lt;continue_msg&amp;gt; d( g, body(&quot;D&quot;));
    continue_node&amp;lt;continue_msg&amp;gt; e( g, body(&quot;E&quot;));

    make_edge( start, a );
    make_edge( start, b );
    make_edge( a, c );
    make_edge( b, c );
    make_edge( c, d );
    make_edge( a, e );

    for (int i = 0; i &amp;lt; 3; ++i ) {
        start.try_put( continue_msg() );
        g.wait_for_all();
    }

    return 0;
}
&lt;/pre&gt;
&lt;br /&gt;
The trouble with the code above is that the graph definition is not declarative. Looking at the series of make_edge calls, it is very hard to visualize the graph. I wanted to see if the situation could be improved...&lt;br /&gt;
&lt;h2&gt;






















Boost.Proto&lt;/h2&gt;
I first encountered Boost.Proto at the&amp;nbsp;Extraordinary C++ conference in 2007. Eric Niebler, the author of the library, gave a presentation to an awestruck audience where he took C++ metaprogramming to a level not seen before. In 2010, Eric wrote a series (&lt;a href=&quot;http://cpp-next.com/archive/2010/08/expressive-c-introduction/&quot;&gt;1&lt;/a&gt;, &lt;a href=&quot;http://cpp-next.com/archive/2010/09/expressive-c-playing-with-syntax/&quot;&gt;2&lt;/a&gt;, &lt;a href=&quot;http://cpp-next.com/archive/2010/09/expressive-c-why-template-errors-suck-and-what-you-can-do-about-it/&quot;&gt;3&lt;/a&gt;, &lt;a href=&quot;http://cpp-next.com/archive/2010/10/expressive-c-expression-extension-part-one/&quot;&gt;4&lt;/a&gt;, &lt;a href=&quot;http://cpp-next.com/archive/2010/10/expressive-c-expression-extension-part-two/&quot;&gt;5&lt;/a&gt;, &lt;a href=&quot;http://cpp-next.com/archive/2010/11/expressive-c-fun-with-function-composition/&quot;&gt;6&lt;/a&gt;, &lt;a href=&quot;http://cpp-next.com/archive/2010/11/expressive-c-trouble-with-tuples/&quot;&gt;7&lt;/a&gt;, &lt;a href=&quot;http://cpp-next.com/archive/2011/01/expressive-c-expression-optimization/&quot;&gt;8&lt;/a&gt;) of articles on the subject that were published on &lt;a href=&quot;http://cpp-next.com/&quot;&gt;C++Next&lt;/a&gt; blog. Through this wonderful series, I was finally able to start wrapping my head around Boost.Proto. The library is actually designed for library writers, more specifically those that are interested in developing an&amp;nbsp;embeddable&amp;nbsp;&lt;a href=&quot;http://en.wikipedia.org/wiki/Domain_specific_language&quot;&gt;DSL&lt;/a&gt;&amp;nbsp;inside C++ programs. I am not going try to give a tutorial of Boost.Proto in this post. If you have not yet done so, I highly recommend reading the aforementioned articles. What I hope to do is document my experience of using Boost.Proto for this&amp;nbsp;exercise.&lt;br /&gt;
&lt;h2&gt;






















Intel TBB meets Boost.Proto&lt;/h2&gt;
To make the TBB&#39;s flow graph construction more declarative, let&#39;s create an EDSL for this task. Ideally the syntax would be as close to the picture of a graph as possible but that turned out to be difficult. Let&#39;s start with a simple case of few nodes in a row:&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWF8DUbucncldhILLy8rb9l2Pk2_ochbbhDCHEgooOTssEhssKdCKg_RXZ5bbZ51yIEtMY9Tco9iapUIlO8JPZYux2XfDIMRzWxxkkre7Sg7-f3TtfGx1lf4GICx6SJly_v0LmHoA_yP9H/s1600/graph1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWF8DUbucncldhILLy8rb9l2Pk2_ochbbhDCHEgooOTssEhssKdCKg_RXZ5bbZ51yIEtMY9Tco9iapUIlO8JPZYux2XfDIMRzWxxkkre7Sg7-f3TtfGx1lf4GICx6SJly_v0LmHoA_yP9H/s1600/graph1.png&quot; /&gt;&lt;/a&gt;
&lt;br /&gt;
In the EDSL we will write this as&amp;nbsp;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;a &amp;gt; b &amp;gt; c&lt;/span&gt;. Next, let&#39;s look at graphs where a node has more than one edge coming out of it or going into it:
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBgjq9cZZ3A63x6pafRACmhUsDyCxOnKH6PjWcJSH2tLB1HqtrdI0iNg0CQWYI-_Yzjoyqf_YgRGoVpQBeUE6Fagz8QGioDmywwlQXmhdFvO7wwoLEQnGuyaNPUrA4E71ANcU25YwyuGqg/s1600/graph2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjBgjq9cZZ3A63x6pafRACmhUsDyCxOnKH6PjWcJSH2tLB1HqtrdI0iNg0CQWYI-_Yzjoyqf_YgRGoVpQBeUE6Fagz8QGioDmywwlQXmhdFvO7wwoLEQnGuyaNPUrA4E71ANcU25YwyuGqg/s1600/graph2.png&quot; /&gt;&lt;/a&gt;&amp;nbsp;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgITkAwVEvY_HOsVa96Mu-IoXB6wlAE9vRJI8vdrJtCYgi4e4K2itDMFuV0vtmE-mnQcahuNOm5cKFXkV5niss4vUqGk0BJAVzOMIFYW2zQI3LgeMm8hC3jnHnJ1HE35HeWC25serNX9Ar1/s1600/graph3.png&quot; imageanchor=&quot;1&quot; style=&quot;background-color: white; margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgITkAwVEvY_HOsVa96Mu-IoXB6wlAE9vRJI8vdrJtCYgi4e4K2itDMFuV0vtmE-mnQcahuNOm5cKFXkV5niss4vUqGk0BJAVzOMIFYW2zQI3LgeMm8hC3jnHnJ1HE35HeWC25serNX9Ar1/s1600/graph3.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
We will write the left graph as &lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;a &amp;gt; (b + c)&lt;/span&gt; and the right one as &lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;(a + b) &amp;gt; c&lt;/span&gt;. Since when I see graphs like this, I tell to myself &quot;a goes to b and c&quot; and &quot;a and b go to c&quot;, this syntax seems reasonable. And since in C++ the addition has higher precedence than greater operator, the parenthesis can be dropped: &lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;a &amp;gt; b + c&lt;/span&gt; and &lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;a + b &amp;gt; c&lt;/span&gt;.&amp;nbsp;Let&#39;s use this syntax to express the graph in the original example:&amp;nbsp;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;start &amp;gt; (a &amp;gt; e + c)&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;+ (b &amp;gt; c &amp;gt; d)&lt;/span&gt;.&lt;/div&gt;
&lt;h2&gt;






















The Grammar&lt;/h2&gt;
As I started working on defining a grammar for this mini language, I first defined it on paper using EBNF notation much like I would do if I was going to use yacc:
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;expr ::= expr &quot;&amp;gt;&quot; group | group&lt;/span&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;group ::= group &quot;+&quot; node |&amp;nbsp;&quot;(&quot; expr &quot;)&quot; | node&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;node ::=&amp;nbsp;broadcast_node |&amp;nbsp;continue_node&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
After a little fumbling however, I realized &amp;nbsp;that Proto grammars can be much simpler. Since Proto expressions are C++ expressions, one does not have to worry about introducing parenthesis into the grammar nor trying to build operator precedence and associativity into it. Thus the grammar actually becomes:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;expr ::= expr &quot;&amp;gt;&quot; expr&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| expr &quot;+&quot; expr&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| broadcast_node&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| continue_node&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
A grammar like this would usually be&amp;nbsp;ambiguous&amp;nbsp;as it would be unclear how parse a &amp;gt; b &amp;gt; c, for example. But since C++ dictates the operator rules for us, there is no such ambiguity with Proto grammars! Written in Proto (transforms replaced with ellipses for now), it becomes:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;namespace flow = tbb::flow;
namespace proto = boost::proto;
typedef flow::broadcast_node&amp;lt;flow::continue_msg&amp;gt; bcast_node;
typedef flow::continue_node&amp;lt;flow::continue_msg&amp;gt; cont_node;
typedef proto::literal&amp;lt;bcast_node&amp;gt; bcast;
typedef proto::literal&amp;lt;cont_node&amp;gt; cont;

struct grammar
    : proto::or_&amp;lt;
        proto::when&amp;lt;proto::plus&amp;lt;grammar, grammar&amp;gt;, ...&amp;gt;,
        proto::when&amp;lt;proto::greater&amp;lt;grammar, grammar&amp;gt;, ...&amp;gt;,
        proto::when&amp;lt;bcast, ...&amp;gt;,
        proto::when&amp;lt;cont, ...&amp;gt;
    &amp;gt;
{};
&lt;/pre&gt;
&lt;br /&gt;
&lt;h2&gt;











The Transforms&lt;/h2&gt;
With the grammar in place, it&#39;s time to make it actually do stuff. We need to put in semantic actions, or transforms as Proto calls it, next to each grammar rule. In TBB, each node is both a sender and receiver of messages (and is derived from sender&amp;lt;T&amp;gt; and receiver&amp;lt;T&amp;gt;). As we combine the nodes together using the two operators, we produce a compound node which has some of the nodes inside of it acting as its senders and some as receivers. For example, suppose we have an expression &lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;(a &amp;gt; b) &amp;gt; (c &amp;gt; d &amp;gt; e)&lt;/span&gt; and we have independently build up two compound nodes,&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt; (a &amp;gt; b)&lt;/span&gt; and &lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;(c &amp;gt; d &amp;gt; e)&lt;/span&gt;. We now join the two using the &amp;gt; operator. The &amp;gt; operator splices together the left-hand&#39;s senders with right-hand&#39;s receivers. In the diagrams below, the box &amp;nbsp;represents the compound node, the receivers are colored blue, the senders are colored red and nodes acting as both receivers and senders are colored purple. For the example above, the following diagram illustrates the before and after the splice. Note that while &#39;a&#39; is sending messages to &#39;b&#39;, it is actually the receiver of the compound node.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsDm6hxqFUndEbKrcxq8uaM4QmO2TZ3YzZEW9HEKFRz44cxUDiMdJ4snaaEypUPdT700P928kTk_33ibrYNcUUh4d4EJCofCF0QLZpUi2WAWObdG-p9jkXJz318dVybW84YLry3pSOvi-N/s1600/graph4.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsDm6hxqFUndEbKrcxq8uaM4QmO2TZ3YzZEW9HEKFRz44cxUDiMdJ4snaaEypUPdT700P928kTk_33ibrYNcUUh4d4EJCofCF0QLZpUi2WAWObdG-p9jkXJz318dVybW84YLry3pSOvi-N/s1600/graph4.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
The + operator joins the two compound nodes by combining the left-hand&#39;s receivers with right-hand&#39;s receivers and left-hand&#39;s senders with right-hand&#39;s senders. Again, suppose for the expression &lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;(a &amp;gt; b) + (c + d)&lt;/span&gt; we are joining &lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;(a &amp;gt; b)&lt;/span&gt; with &lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;(c + d)&lt;/span&gt;. The following diagram shows the before and after:&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwo8d2Zi9m8Tq7pu-E8SUQeMNzHF4bISTl9Luv7337uMDz7slq96XIiyRo4EZHjl5c2_SkqEL0HiVMzAXCEXOGXOqT-pnJjwPeIWPjbv2XLdI5tXWoSyMvarPWKLR985ihQ1Bo7LxGzmCT/s1600/graph5.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwo8d2Zi9m8Tq7pu-E8SUQeMNzHF4bISTl9Luv7337uMDz7slq96XIiyRo4EZHjl5c2_SkqEL0HiVMzAXCEXOGXOqT-pnJjwPeIWPjbv2XLdI5tXWoSyMvarPWKLR985ihQ1Bo7LxGzmCT/s1600/graph5.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
Finally, let&#39;s go back to the &amp;gt; operator for the case when there are multiple senders being spliced to multiple receivers. In that case we splice each of the lefthand&#39;s senders to each of the right-hand&#39;s receivers. Thus, executing &amp;gt; operator on expressions &lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;(a + b)&lt;/span&gt; and &lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;(c + d + e)&lt;/span&gt; results in the following graph:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVZPFR4O5fUBVgCFUg2We0zkdh9GNX84QUqh9zTz17pr5hT309miGC4HOav9A-vVhB-tWd2v7wH2nzsFd7kAZH2TcWigmv07eUZ87Q_2OcfKICrqj-wjt5Y4zw4510NJ-3ir4qKz6qsSdu/s1600/graph6.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVZPFR4O5fUBVgCFUg2We0zkdh9GNX84QUqh9zTz17pr5hT309miGC4HOav9A-vVhB-tWd2v7wH2nzsFd7kAZH2TcWigmv07eUZ87Q_2OcfKICrqj-wjt5Y4zw4510NJ-3ir4qKz6qsSdu/s1600/graph6.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
We now have all the pieces to start looking at code. Here are some typedefs:&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;
&lt;/div&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;typedef std::set&amp;lt;flow::sender&amp;lt;flow::continue_msg&amp;gt;*&amp;gt; sender_set;
typedef std::set&amp;lt;flow::receiver&amp;lt;flow::continue_msg&amp;gt;*&amp;gt; receiver_set;
typedef std::tuple&amp;lt;sender_set, receiver_set&amp;gt; compound_node;
&lt;/pre&gt;
&lt;br /&gt;
Next up is the easiest of the transforms. When we encounter the terminals, broadcast_node or continue_node, we make a compound_node that only has that node inside of it:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;struct make_compound_node : proto::callable
    typedef compound_node result_type;

    compound_node operator()(flow::sender&amp;lt;flow::continue_msg&amp;gt;&amp;amp; s, flow::receiver&amp;lt;flow::continue_msg&amp;gt;&amp;amp; r) {
        return compound_node({&amp;amp;s}, {&amp;amp;r});
    }
};

struct grammar
    : proto::or_&amp;lt;
        proto::when&amp;lt;proto::plus&amp;lt;grammar, grammar&amp;gt;, ...&amp;gt;,
        proto::when&amp;lt;proto::greater&amp;lt;grammar, grammar&amp;gt;, ...&amp;gt;,
        proto::when&amp;lt;bcast, make_compound_node(proto::_value, proto::_value)&amp;gt;,
        proto::when&amp;lt;cont, make_compound_node(proto::_value, proto::_value)&amp;gt;
&amp;gt;
{};
&lt;/pre&gt;
&lt;br /&gt;
Next, we take care of + operator. Remember, we just need to join the two senders&#39; sets into one and do the same for the receivers&#39; sets:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;struct join : proto::callable {
    typedef compound_node result_type;
    compound_node operator()(compound_node left, compound_node right) const {
        sender_set&amp;amp; senders = std::get&amp;lt;0&amp;gt;(left);
        senders.insert(std::get&amp;lt;0&amp;gt;(right).begin(), std::get&amp;lt;0&amp;gt;(right).end());

        receiver_set&amp;amp; receivers = std::get&amp;lt;1&amp;gt;(left);
        receivers.insert(std::get&amp;lt;1&amp;gt;(right).begin(), std::get&amp;lt;1&amp;gt;(right).end());

        return compound_node(std::move(senders), std::move(receivers));
    };
};

struct grammar
    : proto::or_&amp;lt;
        proto::when&amp;lt;proto::plus&amp;lt;grammar, grammar&amp;gt;, join(grammar(proto::_left), grammar(proto::_right))&amp;gt;,
        proto::when&amp;lt;proto::greater&amp;lt;grammar, grammar&amp;gt;, ...&amp;gt;,
        proto::when&amp;lt;bcast, make_compound_node(proto::_value, proto::_value)&amp;gt;,
        proto::when&amp;lt;cont, make_compound_node(proto::_value, proto::_value)&amp;gt;
&amp;gt;
{};
&lt;/pre&gt;
&lt;br /&gt;
And finally the &amp;gt; operator:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;struct splice : proto::callable {
    typedef compound_node result_type;

    compound_node operator()(compound_node left, compound_node right) const {
        for( auto s: std::get&amp;lt;0&amp;gt;(left) )
            for( auto r: std::get&amp;lt;1&amp;gt;(right) )
                flow::make_edge(*s, *r);

        sender_set&amp;amp; senders = std::get&amp;lt;0&amp;gt;(right);
        receiver_set&amp;amp; receivers = std::get&amp;lt;1&amp;gt;(left);

        return compound_node(std::move(senders), std::move(receivers));
    }
};

struct grammar
    : proto::or_&amp;lt;
        proto::when&amp;lt;proto::plus&amp;lt;grammar, grammar&amp;gt;, join(grammar(proto::_left), grammar(proto::_right))&amp;gt;,
        proto::when&amp;lt;proto::greater&amp;lt;grammar, grammar&amp;gt;, splice(grammar(proto::_left), grammar(proto::_right))&amp;gt;,
        proto::when&amp;lt;bcast, make_compound_node(proto::_value, proto::_value)&amp;gt;,
        proto::when&amp;lt;cont, make_compound_node(proto::_value, proto::_value)&amp;gt;
&amp;gt;
{};&lt;/pre&gt;
&lt;br /&gt;
The only thing that is left is main() demonstrating the usage:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;int main() {

    flow::graph g;

    bcast start(g);
    cont a = cont_node( g, body(&quot;A&quot;));
    cont b = cont_node( g, body(&quot;B&quot;));
    cont c = cont_node( g, body(&quot;C&quot;));
    cont d = cont_node( g, body(&quot;D&quot;));
    cont e = cont_node( g, body(&quot;E&quot;));

    auto expr =
        start &amp;gt; (a &amp;gt; e + c)
              + (b &amp;gt; c &amp;gt; d);

    grammar()(expr);

    proto::value(start).try_put( flow::continue_msg() );
    g.wait_for_all();

    return 0;
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;i&gt;A big thanks goes to Neil Groves for reviewing this article.&lt;/i&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev-perspective.blogspot.com/feeds/6478579165225151476/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dev-perspective.blogspot.com/2012/07/fun-with-intel-tbb-and-boostproto.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/6478579165225151476'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/6478579165225151476'/><link rel='alternate' type='text/html' href='http://dev-perspective.blogspot.com/2012/07/fun-with-intel-tbb-and-boostproto.html' title='Fun with Intel TBB and Boost.Proto'/><author><name>Eugene</name><uri>http://www.blogger.com/profile/15405098005234713619</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUMlomdRN5GbbnnXFvHrFOR-Nf-Xy8QoZJaqh8gaoLdMki7QRMIoSGKzWKqurIe0zTIxiOKZNp17aWT1Zapx0lVhQFs_Qw3cI89VzdJA8GYkGnGGn8IL2RcFWFvvrsz5ZDhsaohiZ4MrjI/s72-c/dep_graph.jpg" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7098284592115366563.post-7194459177623959401</id><published>2012-03-16T20:26:00.001-07:00</published><updated>2012-04-19T10:04:44.860-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Boost"/><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="C++11"/><category scheme="http://www.blogger.com/atom/ns#" term="D"/><category scheme="http://www.blogger.com/atom/ns#" term="Go"/><title type='text'>Deferring execution</title><content type='html'>Go language has&amp;nbsp;&lt;a href=&quot;http://golang.org/doc/go_spec.html#Defer_statements&quot;&gt;defer statements&lt;/a&gt;&amp;nbsp;which allow for postponing execution of a function or method call until the end of the current function. Similarly, D has&amp;nbsp;&lt;a href=&quot;http://dlang.org/statement.html#ScopeGuardStatement&quot;&gt;scope guard statements&lt;/a&gt;&amp;nbsp;which allow statement execution to be delayed until the end of the scope (optionally specified to only execute under successful or failed scenarios).&lt;br /&gt;
&lt;br /&gt;
&lt;table border=&quot;0&quot; cellspacing=&quot;10&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;b&gt;Go&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;D&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;pre&gt;lock(l)
// unlocking happens before
// surrounding function returns
defer unlock(l)
&lt;/pre&gt;
&lt;/td&gt;&lt;td&gt;&lt;br /&gt;&lt;/td&gt;&lt;td&gt;&lt;pre&gt;lock(l);
// unlock on leaving the scope
scope(exit) unlock(l);
&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
This is similar to &#39;finally&#39; statements that are used in languages like Java and Python. In C++, we have our trusty&amp;nbsp;&lt;a href=&quot;http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization&quot;&gt;RAII technique&lt;/a&gt;&amp;nbsp;to execute clean up code at the end of scope. But for the cases when that is not convenient, boost provides&amp;nbsp;&lt;a href=&quot;http://www.boost.org/doc/libs/1_49_0/libs/scope_exit/doc/html/index.html&quot;&gt;ScopeExit&lt;/a&gt;&amp;nbsp;library to accomplish something akin to D:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;lock(l);
BOOST_SCOPE_EXIT( (&amp;amp;l) )
{
    unlock(l);
} BOOST_SCOPE_EXIT_END
&lt;/pre&gt;
&lt;br /&gt;
If you look at Boost.ScopeExit source, it is filled with enough macro magic to make your head spin. The upside is that it works with C++03. But with C++11 and lambdas, we can build the same functionality and more with easy to read, macro free code.&lt;br /&gt;
&lt;br /&gt;
The basic idea is to put deferred code into a lambda function and then store the lambda in a class that will execute it when it destructs. Let&#39;s start with this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;typename F&amp;gt;
struct deferrer {
    F fun;
    ~deferrer() { fun(); }
};

template &amp;lt;typename F&amp;gt;
deferrer&amp;lt;F&amp;gt; defer(F const&amp;amp; f) {
    return deferrer&amp;lt;F&amp;gt;{ f };
}
&lt;/pre&gt;
With this simple class (struct for now) and helper function, we can defer code like this:&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;void foo() {
    lock_t l;
    lock(l);
    auto d = defer([&amp;amp;l] { unlock(l); });
    // ...
}
&lt;/pre&gt;
&lt;br /&gt;
However, there are a number of problems with this code. First, if lambda function throws, we will get a throwing destructor and the program will go to terminate() in those cases when the stack was already being unwound due to an exception. We can either leave things as is and disallow deferred code to throw or surround fun() invokation in try/catch block. Since this problem plaques RAII as well, I&#39;ll just resort to the former.&lt;br /&gt;
&lt;br /&gt;
Second, and more serious problem, is that deferrer&amp;lt;F&amp;gt; is copyable and since defer() returns the object by value, there will be temporaries that get constructed and destructed. Since the destructor executes our function, our deferred code will get executed multiple times and prematurely! Well, that&#39;s the worst case scenario. Most compilers now implement copy elision and so &lt;a href=&quot;http://en.wikipedia.org/wiki/Return_value_optimization&quot;&gt;RVO&lt;/a&gt; will actually not make this scenario appear. But relying on a compiler optimization is a bad practice anyway.&lt;br /&gt;
&lt;br /&gt;
You might be saying right now, &quot;wait a minute, this is C++11, shouldn&#39;t the return value be moved instead of copied?&quot;. Yes, if the move constructor is available. But by defining the destructor, we opted out of move constructor (and move assignment operator) being implicitly defined for us. Remember, the C++ committee tightened the rules regarding when the implicit generation is OK. Dave Abrahams has a nice &lt;a href=&quot;http://cpp-next.com/archive/2011/02/w00t-w00t-nix-nix/&quot;&gt;post&lt;/a&gt; on the topic. BTW, gcc 4.6 still generates the move constructor and I haven&#39;t tested the soon to be released 4.7.&lt;br /&gt;
&lt;br /&gt;
The best thing to do here is to forbid copying and define a move constructor:&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;typename F&amp;gt;
class deferrer {
    F fun;
    bool enabled;

public:
    deferrer(F const&amp;amp; f) : fun(f), enabled(true) {}

    // move constructor
    deferrer(deferrer&amp;lt;F&amp;gt;&amp;amp;&amp;amp; rhs) : fun(rhs.fun), enabled(rhs.enabled) {
        rhs.enabled = false;
    }

    // move assignment
    deferrer&amp;lt;F&amp;gt;&amp;amp; operator=(deferrer&amp;lt;F&amp;gt;&amp;amp;&amp;amp; rhs) {
        if( this != &amp;amp;rhs ) {
            fun = rhs.fun;
            enabled = rhs.enabled;
            rhs.enabled = false;
        }
        return *this;
    }

    // no copying
    deferrer(deferrer&amp;lt;F&amp;gt; const&amp;amp; ) = delete;
    deferrer&amp;lt;F&amp;gt;&amp;amp; operator=(deferrer&amp;lt;F&amp;gt; const&amp;amp;) = delete;

    ~deferrer() {
        if( enabled )
            fun();
    }

    // add this as a bonus 
    void cancel() { enabled = false; }
};
&lt;/pre&gt;
&lt;br /&gt;
Now let&#39;s turn our attention to the case when the deferred action should happen not at the end of lexical scope of where deferment was specified but at the end of the function scope or the end of some other lexical scope. For example:&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;void foo(const char* path, bool cleanup) {
    int fd = creat(path, S_IRUSR);
    if( cleanup ) {
        auto d = defer([path, fd]{
            close(fd);
            unlink(path);
        });
    }
    else {
        auto d = defer([fd]{ close(fd); });
    }
    // oops, closed and maybe unlinked too early!
    // ....
}
&lt;/pre&gt;
&lt;br /&gt;
We can fix this by creating another class that we can instantiate in the lexical scope at the end of which we want the deferred action to be executed:&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;void foo(const char* path, bool cleanup) {
    deferred d; // deferred action will execute at the end of foo()
    int fd = creat(path, S_IRUSR);
    if( cleanup ) {
        d = defer([path, fd]{
            close(fd);
            unlink(path);
        });
    }
    else {
        d = defer([fd]{ close(fd); });
    }
    // ....
}
&lt;/pre&gt;
To implement such a beast, we&#39;ll need to use std::function to type erase the lambda into nullary function:&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;typename F&amp;gt;
class deferrer {
    friend class deferred;
    // remainder not changed
};

class deferred {
    std::function&amp;lt;void ()&amp;gt; fun;

public:
    deferred() = default;
    deferred(deferred const&amp;amp;) = delete;
    deferred&amp;amp; operator=(deferred const&amp;amp;) = delete;

    template &amp;lt;typename F&amp;gt;
    deferred(deferrer&amp;lt;F&amp;gt;&amp;amp;&amp;amp; d) {
        if( d.enabled ) {
            fun = d.fun;
            d.enabled = false;
        }
    }

    ~deferred() {
        if( fun )
            fun();
    }
};
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Conclusion&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
While I think that the time it takes to define an RAII object is well spent, I admit that the occasional use of scope exit facility can be convenient. It is also great to see that lambda functions allow us to implement few simple utility classes that can do what other languages had to provide in the language itself.</content><link rel='replies' type='application/atom+xml' href='http://dev-perspective.blogspot.com/feeds/7194459177623959401/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dev-perspective.blogspot.com/2012/03/deferring-execution.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/7194459177623959401'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/7194459177623959401'/><link rel='alternate' type='text/html' href='http://dev-perspective.blogspot.com/2012/03/deferring-execution.html' title='Deferring execution'/><author><name>Eugene</name><uri>http://www.blogger.com/profile/15405098005234713619</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7098284592115366563.post-6724305023619124011</id><published>2012-03-03T16:29:00.000-08:00</published><updated>2012-04-19T10:04:19.004-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="C++11"/><category scheme="http://www.blogger.com/atom/ns#" term="metaprogramming"/><title type='text'>Recursing constexpr - Part II</title><content type='html'>In the &lt;a href=&quot;http://dev-perspective.blogspot.com/2012/02/recursing-constexpr.html&quot;&gt;previous post&lt;/a&gt;, we developed a logarithmic depth accumulate() function that can be used to emulate a for-loop. In this post, we&#39;ll look at how to construct a  function that emulates a while-loop with the recursive depth of &lt;i&gt;O(lg(n))&lt;/i&gt; where &lt;i&gt;n&lt;/i&gt; is the number of iterations of the while-loop. Recall that our initial motivation is to be able to determine if a large number is prime at compile time as was done in &lt;a href=&quot;http://cpptruths.blogspot.com/2011/07/want-speed-use-constexpr-meta.html&quot;&gt;this post&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
A while-loop can be generally written as follows:&lt;br /&gt;
&lt;br /&gt;
state = initial state;&lt;br /&gt;
while( test(state) )&lt;br /&gt;
&amp;nbsp; &amp;nbsp; mutate state;&lt;br /&gt;
&lt;br /&gt;
Translating this to functional form, we can write the signature as:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;typename T, typename Test, typename Op&amp;gt;
T while_loop(T init, Test test, Op op);
&lt;/pre&gt;
&lt;br /&gt;
The main idea behind the implementation of while_loop() is to call a helper function that will execute up to &lt;i&gt;n&lt;/i&gt; iterations of the loop. As we have seen in previous post, this can be done with recursive depth of &lt;i&gt;O(lg(n))&lt;/i&gt;. If there are more iterations that are still needed (that is test(state) is still true), while_loop() recursively calls itself with &lt;i&gt;2n&lt;/i&gt;. Instead of &lt;i&gt;n&lt;/i&gt;, the implementation uses &lt;i&gt;depth&lt;/i&gt; argument to signify the maximum recursion depth.&amp;nbsp;This is illustrated below:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWVzt6cYswjAe7QV79OT7swuq9iraiG6-BFhg9R7EZNZhMUoUezh8ZKyQDzk-j76RhrsfRDJURJUSMJUOV-KTAJ1c0Re1UY_1TKgCLDzbot3k2H_LinQvWg8-emC5ychrw-fs2SvXGE8_z/s1600/while-loop.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;211&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWVzt6cYswjAe7QV79OT7swuq9iraiG6-BFhg9R7EZNZhMUoUezh8ZKyQDzk-j76RhrsfRDJURJUSMJUOV-KTAJ1c0Re1UY_1TKgCLDzbot3k2H_LinQvWg8-emC5ychrw-fs2SvXGE8_z/s400/while-loop.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
The code looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;typename T, typename Test, typename Op&amp;gt;
constexpr T exec(int first, int last, T init, Test test, Op op) {
    return
        (first &amp;gt;= last || !test(init)) ? init :
            (first + 1 == last) ?
                op(init) :
                exec((first + last) / 2, last,
                    exec(first, (first + last) / 2, init, test, op), test, op);
}

template &amp;lt;typename T, typename Test, typename Op&amp;gt;
constexpr T while_loop(T init, Test test, Op op, int depth = 1) {
    return !test(init) ? init :
        while_loop(exec(0, (1 &amp;lt;&amp;lt; depth) - 1, init, test, op), test, op, depth+1);
}
&lt;/pre&gt;
&lt;br /&gt;
There is one downside to this algorithm. The exec() function performs the test to determine if it should continue or bail at the point of entry. This performs more tests than necessary. For example, as exec() recurses along the left edge of the tree, it performs the test over and over without mutating the state. This can be fixed by introducing another helper and performing the test only on the right branch of the recursion:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;typename T, typename Test, typename Op&amp;gt;
constexpr T guarded_exec(int first, int last, T init, Test test, Op op) {
    return test(init) ? exec(first, last, init, test, op) : init;
}

template &amp;lt;typename T, typename Test, typename Op&amp;gt;
constexpr T exec(int first, int last, T init, Test test, Op op) {
    return
        (first &amp;gt;= last) ? init :
            (first + 1 == last) ?
                op(init) :
                guarded_exec((first + last) / 2, last,
                    exec(first, (first + last) / 2, init, test, op), test, op);
}
&lt;/pre&gt;
&lt;br /&gt;
Finally, we can use while_loop() to implement is_prime():&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;struct test_expr {
    int n;
    constexpr bool operator()(int x) const { return x*x &amp;lt;= n &amp;amp;&amp;amp; n % x != 0; }
};

constexpr int inc(int x) {
    return x + 1;
}

constexpr bool gt_than_sqrt(int x, int n) {
    return x*x &amp;gt; n;
}

constexpr bool is_prime(int n) {
    return gt_than_sqrt(while_loop(2, test_expr{ n }, inc), n);
}

int main() {
    static_assert(is_prime(94418953), &quot;should be prime&quot;);
    return 0;
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Logarithmic Growth&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
To see that the recursion depth will be &lt;i&gt;O(lg(n))&lt;/i&gt; where &lt;i&gt;n&lt;/i&gt; is the iteration count, observe that when the last iteration completes, while_loop() will have a recursive depth &lt;i&gt;d&lt;/i&gt; and exec() will also produce depth &lt;i&gt;d&lt;/i&gt;. Thus, the maximum recursion depth will be &lt;i&gt;2d&lt;/i&gt;. At the first level, exec() would have completed 1 iterations, 3 at the second, 7 at the third, and &lt;a href=&quot;http://www.codecogs.com/eqnedit.php?latex=2^d-1&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://latex.codecogs.com/gif.latex?2^d-1&quot; title=&quot;2^d-1&quot; /&gt;&lt;/a&gt; at level &lt;i&gt;d&lt;/i&gt;. If &lt;a href=&quot;http://www.codecogs.com/eqnedit.php?latex=d%20=%20\left%20\lceil%20lg(n)%20\right%20\rceil&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://latex.codecogs.com/gif.latex?d = \left \lceil lg(n) \right \rceil&quot; title=&quot;d = \left \lceil lg(n) \right \rceil&quot; /&gt;&lt;/a&gt;, we need to show that&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://www.codecogs.com/eqnedit.php?latex=\sum_{i=1}^{\left%20\lceil%20lg(n)%20\right%20\rceil}2^i-1%20\geq%20n&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://latex.codecogs.com/gif.latex?\sum_{i=1}^{\left \lceil lg(n) \right \rceil}2^i-1 \geq n&quot; title=&quot;\sum_{i=1}^{\left \lceil lg(n) \right \rceil}2^i-1 \geq n&quot; /&gt;&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
for all sufficiently large&amp;nbsp;&lt;i&gt;n&lt;/i&gt;. In that case, the recursion of depth &lt;a href=&quot;http://www.codecogs.com/eqnedit.php?latex=\left%20\lceil%20lg(n)%20\right%20\rceil&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://latex.codecogs.com/gif.latex?\left \lceil lg(n) \right \rceil&quot; title=&quot;\left \lceil lg(n) \right \rceil&quot; /&gt;&lt;/a&gt; can fit more than &lt;i&gt;n&lt;/i&gt; iterations. By the use of geometric series formula, the sum becomes&amp;nbsp;&lt;a href=&quot;http://www.codecogs.com/eqnedit.php?latex=2^{\left%20\lceil%20lg(n)%20\right%20\rceil@plus;1}-\left%20\lceil%20lg(n)%20\right%20\rceil-2&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://latex.codecogs.com/gif.latex?2^{\left \lceil lg(n) \right \rceil+1}-\left \lceil lg(n) \right \rceil-2&quot; title=&quot;2^{\left \lceil lg(n) \right \rceil+1}-\left \lceil lg(n) \right \rceil-2&quot; /&gt;&lt;/a&gt;;&amp;nbsp;and since the first term is dominating, we just need to show that&amp;nbsp;&lt;a href=&quot;http://www.codecogs.com/eqnedit.php?latex=2^{\left%20\lceil%20lg(n)%20\right%20\rceil@plus;1}\geq%20n&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://latex.codecogs.com/gif.latex?2^{\left \lceil lg(n) \right \rceil+1}\geq n&quot; title=&quot;2^{\left \lceil lg(n) \right \rceil+1}\geq n&quot; /&gt;&lt;/a&gt;. Note that&amp;nbsp;&lt;a href=&quot;http://www.codecogs.com/eqnedit.php?latex=2^{\left%20\lceil%20lg(n)@plus;1%20\right%20\rceil}=2(2^{\left%20\lceil%20lg(n)%20\right%20\rceil})\geq%202n\geq%20n&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://latex.codecogs.com/gif.latex?2^{\left \lceil lg(n)+1 \right \rceil}=2(2^{\left \lceil lg(n) \right \rceil})\geq 2n\geq n&quot; title=&quot;2^{\left \lceil lg(n)+1 \right \rceil}=2(2^{\left \lceil lg(n) \right \rceil})\geq 2n\geq n&quot; /&gt;&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Practical Simplification&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Since our initial goal was to not exceed the compiler recursion limit, we do not actually need truly logarithmic depth. It will suffice to map the loop iterations onto a tree of certain depth. For example, if we choose a depth of 30, we can have up to &lt;a href=&quot;http://www.codecogs.com/eqnedit.php?latex=2^{30}=1073741823&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://latex.codecogs.com/gif.latex?2^{30}=1073741823&quot; title=&quot;2^{30}=1073741823&quot; /&gt;&lt;/a&gt; iterations, more than enough for most practical purposes. In this case, the while_loop() function simplifies to:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;typename T, typename Test, typename Op&amp;gt;
constexpr T while_(T init, Test test, Op op) {
    return guarded_accumulate(0, (1 &amp;lt;&amp;lt; 30) - 1, init, test, op);
}
&lt;/pre&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://dev-perspective.blogspot.com/feeds/6724305023619124011/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dev-perspective.blogspot.com/2012/03/recursing-constexpr-part-ii.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/6724305023619124011'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/6724305023619124011'/><link rel='alternate' type='text/html' href='http://dev-perspective.blogspot.com/2012/03/recursing-constexpr-part-ii.html' title='Recursing constexpr - Part II'/><author><name>Eugene</name><uri>http://www.blogger.com/profile/15405098005234713619</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWVzt6cYswjAe7QV79OT7swuq9iraiG6-BFhg9R7EZNZhMUoUezh8ZKyQDzk-j76RhrsfRDJURJUSMJUOV-KTAJ1c0Re1UY_1TKgCLDzbot3k2H_LinQvWg8-emC5ychrw-fs2SvXGE8_z/s72-c/while-loop.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7098284592115366563.post-2775997256234330012</id><published>2012-02-24T08:55:00.000-08:00</published><updated>2012-04-19T10:04:09.527-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="C++"/><category scheme="http://www.blogger.com/atom/ns#" term="C++11"/><category scheme="http://www.blogger.com/atom/ns#" term="metaprogramming"/><title type='text'>Recursing a constexpr</title><content type='html'>While reading &quot;&lt;a href=&quot;http://cpptruths.blogspot.com/2011/07/want-speed-use-constexpr-meta.html&quot;&gt;Want speed? Use constexpr meta-programming!&lt;/a&gt;&quot;&amp;nbsp;blog post, I started thinking about how to reduce the recursion depth of such calculations. After all, using a compiler option to increase the recursion depth limits is not very friendly (gcc sets the limit at 512 by default). But before we get to reducing the depth of something like is_prime_func() from the aforementioned post, it&#39;s best to start with something slightly easier.&lt;br /&gt;
&lt;br /&gt;
Consider a function to compute the following series:&lt;br /&gt;
&lt;a href=&quot;http://www.codecogs.com/eqnedit.php?latex=f(a,%20n)%20=%20\sum_{i=1}^{n}%20a(i^2)%20=%20a(1^2)%20@plus;%20a(2^2)%20@plus;%20a(3^2)%20@plus;%20\cdots%20@plus;%20a(n^2)&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://latex.codecogs.com/gif.latex?f(a, n) = \sum_{i=1}^{n} a(i^2) = a(1^2) + a(2^2) + a(3^2) + \cdots + a(n^2)&quot; title=&quot;f(a, n) = \sum_{i=1}^{n} a(i^2) = a(1^2) + a(2^2) + a(3^2) + \cdots + a(n^2)&quot; /&gt;&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
Let&#39;s begin by writing it without constexpr to be executed at runtime but keeping in mind that we will later convert it for compile time computation. We can write it as a recursive accumulate function to gain some generality:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;typename Int, typename T, typename BinOp&amp;gt;
T accumulate(Int first, Int last, T init, BinOp op) {
    return (first &amp;gt;= last) ?
        init :
        accumulate(first+1, last, op(init, first), op);
}

int sum_squares(int a, int n) {
    return accumulate(1, n+1, 0, [a](int prev, int i) {
        return prev + a*i*i;
    });
}
&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
accumulate&#39;s signature is very similar to std::accumulate except that instead of dealing with iterators into a sequence, it operates directly on the integral sequence. The sum_squares function calls accumulate() with a lambda expression that captures &#39;a&#39;.&lt;br /&gt;
&lt;br /&gt;
All is good except that accumulate() will produce a recursion depth equal to the length of the input sequence. We can change it to a logarithmic growth by recursively dividing the sequence into two halves:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;typename Int, typename T, typename BinOp&amp;gt;
T accumulate(Int first, Int last, T init, BinOp op) {
    return
        (first &amp;gt;= last ? init :
            (first+1 == last) ?
                op(init, first) :
                accumulate((first + last) / 2, last,
                    accumulate(first, (first + last) / 2, init, op), op));
}
&lt;/pre&gt;
&lt;br /&gt;
At this point we should be able to just prefix function signatures with constexpr and get the magic of compile time computation. Let&#39;s give it a try:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;template &amp;lt;typename Int, typename T, typename BinOp&amp;gt;
constexpr T accumulate(Int first, Int last, T init, BinOp op) {
    return
        (first &amp;gt;= last ? init :
            (first+1 == last) ?
                op(init, first) :
                accumulate((first + last) / 2, last,
                    accumulate(first, (first + last) / 2, init, op), op));
}

constexpr int sum_squares(int a, int n) {
    return accumulate(1, n+1, 0, [a](int prev, int i) {
        return prev + a*i*i;
    });
}

int main() {
    static_assert(sum_squares(3, 600) == 216540300, &quot;&quot;);
    return 0;
}&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre&gt;$ g++ -std=c++0x test.cpp
test.cpp: In function ‘int sum_squares(int, int)’:
test.cpp:17:1: error: ‘constexpr T accumulate(Int, Int, T, BinOp) [with Int = int, T = int, BinOp = sum_squares(int, int)::&amp;lt;lambda(int, int)&amp;gt;]’ is not ‘constexpr’
test.cpp: In function ‘int main()’:
test.cpp:21:2: error: non-constant condition for static assertion
test.cpp:21:34: error: ‘int sum_squares(int, int)’ is not a constexpr function
&lt;/pre&gt;
&lt;br /&gt;
For some mysterious reason, C++11 Standard explicitly forbids lambda expressions from being used in constexpr expressions. So we have to fall back to good old functors:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: cpp&quot;&gt;struct add_sq {
    int a;
    constexpr int operator()(int p, int i) const { return p + a*i*i; }
};

constexpr int sum_squares(int a, int n) {
    return accumulate(1, n+1, 0, add_sq{ a });
}
&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Generalization to for-loop&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
It is interesting to note that our accumulate() function can work for arbitrary for-loops of the form: &lt;br /&gt;
&lt;pre&gt;for( int i = start; i &amp;lt; end; i++ )
    body;
&lt;/pre&gt;
To see that, observe that a loop starts with some initial state and then mutates it on every iteration in the body of the loop. Functionally, we can view this mutation as applying an operation of two arguments, an old state and iteration index, to produce the new state. This is precisely what our accumulate function does. Of course, the state might encompass more than just a scalar and we would need a composite type to hold the individual elements. It would be great if std::tuple could work with constexpr but since it doesn&#39;t, it&#39;s easy enough to define a struct to hold the necessary state.&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Conclusion&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
As we have seen, it is&amp;nbsp;straightforward&amp;nbsp;to convert a recursive function with linear depth into one with logarithmic depth if the number of recursions is known at the point of its invocation. This makes it easy to convert a classic for-loop into recursive form with manageable depth. Next time we&#39;ll look at how to convert a while-loop, where the number of iterations is not initially known, into logarithmic depth recursion and in the process define the promised is_prime(n) capable of dealing with very large numbers.</content><link rel='replies' type='application/atom+xml' href='http://dev-perspective.blogspot.com/feeds/2775997256234330012/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://dev-perspective.blogspot.com/2012/02/recursing-constexpr.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/2775997256234330012'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7098284592115366563/posts/default/2775997256234330012'/><link rel='alternate' type='text/html' href='http://dev-perspective.blogspot.com/2012/02/recursing-constexpr.html' title='Recursing a constexpr'/><author><name>Eugene</name><uri>http://www.blogger.com/profile/15405098005234713619</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry></feed>