<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-4168503339888369834</atom:id><lastBuildDate>Sat, 31 Dec 2011 14:14:14 +0000</lastBuildDate><category>futurereference</category><category>i'm on the list now</category><category>spam?</category><category>rxvt</category><category>asdf</category><category>bitcoin</category><category>development</category><category>clbuild</category><category>notaloser</category><category>boost</category><category>serialization</category><category>wtf</category><category>dependencyinjection</category><category>dontreadme</category><category>wla</category><category>clang</category><category>deepinthought</category><category>mfc465-cn</category><category>gtkmm</category><category>opengl</category><category>python</category><category>clsql</category><category>c++0x</category><category>nothingtoseehere</category><category>source control</category><category>docbook</category><category>code</category><category>scons</category><category>quit</category><category>psa</category><category>c++</category><category>bjam</category><category>rant</category><category>boostcon</category><category>broken</category><category>linux</category><category>cl-selenium</category><category>business</category><category>emacs</category><category>tr1</category><category>research</category><category>sbcl</category><category>java</category><category>personal</category><category>hunchentoot</category><category>cl-who</category><category>ajax</category><category>cl-opengl</category><category>bzr</category><category>di</category><category>factor</category><category>weblocks</category><category>gtk</category><category>government</category><category>lisp</category><category>lambda</category><category>30day</category><category>computers</category><category>soapbox</category><category>gui</category><category>slime</category><category>meta</category><category>strictlybusiness</category><category>build</category><category>afk</category><category>software</category><category>buildingsoftware</category><category>parenscript</category><category>svk</category><category>qt</category><category>testing</category><category>ubuntu</category><category>vancpp</category><category>nvidia</category><category>svn</category><category>subversion</category><category>google</category><category>money</category><title>sizeof(uint32t)</title><description>Dodheim reads only four blogs. This is one of them.</description><link>http://uint32t.blogspot.com/</link><managingEditor>noreply@blogger.com (Sohail Somani)</managingEditor><generator>Blogger</generator><openSearch:totalResults>114</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/uint32t" /><feedburner:info uri="uint32t" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>uint32t</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/uint32t" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fuint32t" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-5053012611972276167</guid><pubDate>Sun, 29 May 2011 21:13:00 +0000</pubDate><atom:updated>2011-05-29T17:13:55.220-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">i'm on the list now</category><category domain="http://www.blogger.com/atom/ns#">bitcoin</category><title>Learning about Bitcoin or why I'll never use Bitcoin</title><description>&lt;p style="clear: both"&gt;&lt;a href="http://en.wikipedia.org/wiki/Bitcoin" title="" target="_blank"&gt;Bitcoin&lt;/a&gt; is quite a promising e-currency. Created by some-guy-we-don't-really-know-or-a-double-agent-of-some-kind-who-is-probably-quite-Bitcoin-rich-now, it has some very useful properties:&lt;/p&gt;&lt;ol style="clear: both"&gt;&lt;li&gt;Creation of the money is an implicit and transparent agreement between users. That is, there is no centralized issuing authority and there is a finite quantity. Almost like gold.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It is completely electronic and therefore very cheap to transfer. As a result, transaction fees are "low".&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Transactions are anonymized, yet completely public to avoid against double-spending.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Some crypto stuff to make sure it is as secure as it can be today&lt;/li&gt;&lt;/ol&gt;&lt;p style="clear: both"&gt;The main desired outcome of a currency with these rules is autonomy of the currency from the somewhat arbitrary influence of centralized planners.&lt;/p&gt;&lt;p style="clear: both"&gt;&lt;strong&gt;&lt;u&gt;How you are supposed to use Bitcoin&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p style="clear: both"&gt;So how do you use Bitcoin (BTC) as a consumer or vendor? Let us assume that you already have some BTC in your account.&lt;/p&gt;&lt;p style="clear: both"&gt;&lt;div&gt;&lt;ol style="clear: both"&gt;&lt;li&gt;Visit place of business&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Locate item of interest which costs 0.02 BTC&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Go to cashier&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Pull out smart phone with your Bitcoin wallet or some kind of link to your Bitcoin wallet&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Use QR-code at register to find vendor's payment address. This address will likely be generated at the point of purchase&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Send Bitcoin to that address from your Bitcoin wallet&lt;/li&gt;&lt;li&gt;The cashier and network verifies your payment (speed depends on transaction fee) and you go on your way&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;/p&gt;&lt;p style="clear: both"&gt;&lt;div&gt;This is how it would work today if a business accepted BTC. I expect that if I am wrong and if Bitcoin does indeed take off, there will be clearing houses to speed up transactions like these. I think that these confirmations will necessarily be done outside the network but eventually, the network will also validate these which will be the final settlement step.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;This exchange is appealing for various reasons. My favourite one is that the users of the system itself benefit by confirming transactions. That is, you can make Bitcoin just by verifying transactions.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;strong&gt;&lt;u&gt;Bitcoin Wallet&lt;/u&gt;&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;It is probably useful to discuss where Bitcoins are stored. This location, a file on your hard disk, is called a wallet. It consists of a set of private keys that correspond to each address generated as in the above scenario. This is your vault. If it is stolen in unencrypted form, your money is probably as as good as gone. But the coolest part is that if you have a backup and it was encrypted, you simply transfer the money to an account in a new wallet before the thieves are able to crack the encryption and almost by magic, your money is back again.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;u&gt;Anonymous vs Anonymized&lt;/u&gt;&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Earlier, I said that transactions are &lt;em&gt;anonymized. &lt;/em&gt;This is different from them being &lt;em&gt;anonymous &lt;/em&gt;because an anonymizing technology does not imply anonymity. A transaction being anonymous means untraceable which is something that is quite easy to disprove in the BTC world.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Let's start at the beginning. How do you get BTC? There are a couple of ways. One way involves a lot of geekery and stuff that very few people have time for. This is called Bitcoin mining. For most people, just outright buying BTC like they buy USD is the most convenient. Currency is a proxy for labour so it is fine to buy BTC. As the market will continue to be volatile due to the simultaneous debasing of the USD, demand-side pressure as well as the continuous creation of BTC, I would spread out bigger purchases over a few months.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;A convenient way to buy BTC is through an exchange. So let us walk through that process:&lt;br /&gt;&lt;ol style="clear: both"&gt;&lt;li&gt;Create an account with a BTC exchange. I used &lt;a href="http://bitcoinmarket.com" title="" target="_blank"&gt;Bitcoin Market&lt;/a&gt;. This requires you to give them two things: an email address and a Bitcoin payment address. Notice how your email address is tied to your BTC address.&lt;/li&gt;&lt;li&gt;Figure out the trade you want to make. I used BMBTC for PPUSD where BM = Bitcoin Market and PP = PayPal.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Execute the trade by making a payment to some email address on PayPal.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;When I executed this process, it took a total of 15 minutes for the trade to complete but it was a full hour before the money was in my actual wallet and verified by the network. You must note that this is the equivalent of someone on the other side of the world paying me $10 and someone delivering that $10 to me personally. Not to a bank account, not a promise for $10, but cold hard cash to me personally.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Notice that the process of conveniently buying BTC itself has multiple weak links:&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ol style="clear: both"&gt;&lt;li&gt;Your email address is tied to a Bitcoin address by Bitcoin Market&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Paypal knows who you are definitively through the use of your credit card&lt;/li&gt;&lt;li&gt;Some random dude knows you bought some BTC&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;To avoid leaking too much information, you can create a new receiving address for every trade and update it on the Bitcoin Market. Note that Bitcoin Market has full trade information and PayPal has amount information. To reduce the risk there, you can use anonymizing email services or a special email just for Bitcoin purchases.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;em&gt;&lt;/em&gt;&lt;br /&gt;The main point is that once you use a credit card or a personal email address, your anonymity is compromised.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;That's not such a big deal, to be honest. After all, you already trust a lot of people with your information online.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;strong&gt;&lt;u&gt;De-anonymizing the transactions&lt;/u&gt;&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If the seller of the BTC was interested in which address bought the BTC through the exchange, s/he would just track the blocks for the specific amount.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;When I purchased my BTC, I chose 2 BTC to see how difficult it would be to find in the block explorer. It was pretty easy! Why? Because I knew there would be three related transactions: one for 2, one for 1.99 and one for 0.01 (transaction fee by exchange.) The seller would know this as well.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;So all I did was wait for a few blocks to come through the explorer and opened them all up in a browser tab and searched for 1.99. It took less than a minute.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;So now, the seller of the BTC has tied my name (through Paypal) to an address.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;You may be interested in the &lt;a href="http://blockexplorer.com/tx/ac6276792391e57f6fb55c62e78bce435944b7eb6e475d59fc6e539f0b9f7a6f" title="" target="_blank"&gt;actual transaction&lt;/a&gt; as currently being confirmed by computers worldwide. Because of this decentralized confirmation, it is now impossible for the seller to re-sell the same BTC to someone else.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;strong&gt;&lt;u&gt;Using my Bitcoin or why I'll never use it&lt;/u&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;Can you figure out what I did with my BTC? Actually, you have all the information you need in this blog post. Once you figure it out, you'll understand why I'll never use it. &lt;strong&gt;&lt;em&gt;The first person to add a comment with the right answer and their Bitcoin receiving address will get the remainder of my balance transferred to their Bitcoin address&lt;/em&gt;&lt;/strong&gt;. It's not much, but I probably won't use it...&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;u&gt;How to stay anonymous&lt;/u&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;There are ways to &lt;a href="https://en.bitcoin.it/wiki/Anonymity#Staying_anonymous" title="" target="_blank"&gt;stay anonymous&lt;/a&gt; by obfuscating the block chain. However, this is not right. For a currency to be useful, its primitive form must be practically anonymous and not just anonymizing.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;strong&gt;&lt;u&gt;How I'd change Bitcoin&lt;/u&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;My main issues with Bitcoin:&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;ul style="clear: both"&gt;&lt;li&gt;Not anonymous: Identity "anchors" are very easy to establish by transacting with people as described above. This leads to a situation where an attacker can find out what you spend your BTC on for their own nefarious purposes.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The currency has no decay value. That is, it can be hoarded without consequence. I would like BTC to expire so that the currency can keep circulating. This maintains the value of the currency but prevents hoarding. The block chain has enough information to do this. Miners should be interested in this because it means they can continue to mine forever and keep a healthy Bitcoin economy.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;I think the anonymity problem is the most hard to solve. I am only concerned with the ability to transfer coin between my own accounts &lt;em&gt;easily &lt;/em&gt;without notifying anyone else. If some way could be devised to solve these problems, goodbye centralized currencies.&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/p&gt;&lt;br class='final-break' style='clear: both' /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-5053012611972276167?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/z4abIRELgHc" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/z4abIRELgHc/learning-about-bitcoin-or-why-i-never.html</link><author>noreply@blogger.com (Sohail Somani)</author><thr:total>7</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2011/05/learning-about-bitcoin-or-why-i-never.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-4974156190839098977</guid><pubDate>Wed, 27 Apr 2011 00:13:00 +0000</pubDate><atom:updated>2011-04-26T20:13:59.324-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">c++</category><category domain="http://www.blogger.com/atom/ns#">di</category><category domain="http://www.blogger.com/atom/ns#">code</category><category domain="http://www.blogger.com/atom/ns#">dependencyinjection</category><title>Deconstructing a dependency injection-driven application</title><description>&lt;p style="clear: both"&gt;I've been using my &lt;a href="https://bitbucket.org/cheez/dicpp/wiki/Home" target="_blank"&gt;C++ dependency injection library&lt;/a&gt; for a project in the last year and it's gone pretty well. There are a lot of rough edges but I thought it could be interesting to the 3 of you still subscribed to this blog to de-construct the stock quote application.&lt;/p&gt;&lt;p style="clear: both"&gt;&lt;strong&gt;About the application&lt;/strong&gt;&lt;/p&gt;&lt;p style="clear: both"&gt;The &lt;a href="https://bitbucket.org/cheez/dicpp/src/f35b101eff14/lib/examples/stockquote/" target="_blank"&gt;example&lt;/a&gt; itself is pretty straight forward. You have a choice of 3 stock quote providers: Yahoo!, static and phone. You choose one and ask for a stock quote. Magic happens and your stock quote arrives.&lt;strong&gt;&lt;em&gt;&lt;br /&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p style="clear: both"&gt;&lt;strong&gt;Example session (with some debug output)&lt;/strong&gt;&lt;/p&gt;&lt;pre style="clear: both"&gt;Welcome to the DI Stock Quote App. Simplifying and complicating software development since 2010.&lt;br /&gt;Which stock quote service would you like to use?&lt;br /&gt;1: static&lt;br /&gt;2: phone&lt;br /&gt;3: yahoo&lt;br /&gt;Enter your choice (1-3) and press enter: 3&lt;br /&gt;You chose: yahoo&lt;br /&gt;[DICPP]: No scope constructing: di::type_key&amp;lt;YahooStockQuoteService, void&amp;gt;&lt;br /&gt;[DICPP]: Constructing: di::type_key&amp;lt;di::typed_provider&amp;lt;HttpDownloadService&amp;gt;, void&amp;gt;&lt;br /&gt;[DICPP]: Completed constructing: di::type_key&amp;lt;di::typed_provider&amp;lt;HttpDownloadService&amp;gt;, void&amp;gt; with address: 0x100750&lt;br /&gt;Stock symbol (type quit to quit): goog&lt;br /&gt;[DICPP]: No scope constructing: di::type_key&amp;lt;HttpDownloadService, void&amp;gt;&lt;br /&gt;[DICPP]: Constructing: di::type_key&amp;lt;boost::asio::io_service, void&amp;gt;&lt;br /&gt;[DICPP]: Singleton: constructing: di::type_key&amp;lt;boost::asio::io_service, void&amp;gt;&lt;br /&gt;[DICPP]: Completed constructing: di::type_key&amp;lt;boost::asio::io_service, void&amp;gt; with address: 0x1008a0&lt;br /&gt;Current price for goog: 532.82&lt;br /&gt;Stock symbol (type quit to quit): quit&lt;br /&gt;&lt;/pre&gt;&lt;p style="clear: both"&gt;See how the construction of the HTTP service is automatically delayed until actually needed. This is done through a concept called a "provider" which is basically an automatically generated factory.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;About Dependency Injection&lt;/strong&gt;&lt;/p&gt;&lt;p style="clear: both"&gt;A really good introduction to the dependency injection technique as implemented by &lt;a href="http://code.google.com/p/google-guice/" target="_blank"&gt;Guice&lt;/a&gt; can be found &lt;a href="http://www.youtube.com/watch?v=hBVJbzAagfs" target="_blank"&gt;here&lt;/a&gt;. It's probably one of my favourite tech talks of all time.&lt;/p&gt;&lt;p style="clear: both"&gt;Anyway, to refresh your memory, here are some of the main benefits of the technique used in Guice:&lt;/p&gt;&lt;ul style="clear: both"&gt;&lt;li&gt;Object construction and lifecycle management is mostly handled for you.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Less boilerplate.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Makes code more testable.&lt;/li&gt;&lt;li&gt;Scopes (~object creation/lifecycle) can be customized by the user.&lt;/li&gt;&lt;/ul&gt;&lt;p style="clear: both"&gt;In short: a lot of the time, you no longer need to allocate objects or pass some object unused down multiple layers of functions or object constructors just to use them once way deep down in some code.&lt;/p&gt;&lt;p style="clear: both"&gt;&lt;strong&gt;Magic!&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;I don't really recall how it is done in Guice but in the C++ library linked above, this magic is driven by a type registry which recursively registers constructor arguments as well as user customizations.&lt;/p&gt;&lt;p style="clear: both"&gt;In extreme cases, you can initialize an entire application with a few lines of code:&lt;/p&gt;&lt;pre style="clear: both"&gt;  di::registry r;&lt;br /&gt;  r.add( r.type&amp;lt;MyApplication&amp;gt;() );&lt;br /&gt;  r.construct&amp;lt;shared_ptr&amp;lt;MyApplication&amp;gt;&amp;gt;()-&amp;gt;execute();&lt;/pre&gt;&lt;p style="clear: both"&gt;This constructs the type registry which is a kind of factory. There is a mini-DSL for describing how you want the registry to handle the type. More on this later. In this case, we are asking the registry to "learn" about the MyApplication type as well as all objects that are required for constructing MyApplication.&lt;br /&gt;&lt;br /&gt;"Pish-posh", you say. "MyApplication has a 0-arg constructor. I could do that in my sleep."&lt;/p&gt;&lt;p style="clear: both"&gt;Would you be surprised if I said that the MyApplication type actually has 3 arguments?&lt;/p&gt;&lt;p style="clear: both"&gt;Well, the above is almost what the StockQuote application looks like. Here is the main function for the stock quote example:&lt;/p&gt;&lt;pre style="clear: both"&gt;di::injector inj;&lt;br /&gt;inj.install( StockQuoteAppModule() );&lt;br /&gt;&lt;/pre&gt;&lt;pre style="clear: both"&gt;StockQuoteApp &amp;amp; app = inj.construct&amp;lt;StockQutoeApp&amp;amp;&amp;gt;(); // lifetime&lt;br /&gt;app.execute();&lt;/pre&gt;&lt;p style="clear: both"&gt;And here is the constructor for the StockQuoteApp type:&lt;/p&gt;&lt;pre style="clear: both"&gt;DI_CONSTRUCTOR ( StockQuoteApp ,&lt;br /&gt;                ( boost :: shared_ptr &amp;lt; UserInterface &amp;gt;  ui , &lt;br /&gt;                 boost :: shared_ptr &amp;lt; StockQuoteServiceFactory &amp;gt;  factory ));&lt;/pre&gt;&lt;p style="clear: both"&gt;When we ask the "injector" to construct the StockQuoteApp instance, it automatically creates the UserInterface as well as the StockQuoteServiceFactory instance.&lt;br /&gt;&lt;br /&gt;The di::injector type is just a thin wrapper around the registry so you can treat it as such. The only thing it really provides is a little bit of syntax to allow you to create modules in a similar manner as Guice. The guts of StockQuoteAppModule accept a registry as a parameter and register the various types. You can see the mini-DSL referred to earlier:&lt;/p&gt;&lt;pre style="clear: both"&gt;void&lt;br /&gt;StockQuoteAppModule::operator()( di::registry &amp;amp; r ) const&lt;br /&gt;{&lt;br /&gt;  // In each module we define the module's root objects, in this case,&lt;br /&gt;  // StockQuoteApp as well as implementations/specializations of any&lt;br /&gt;  // abstract classes. For example, UserInterface is an ABC and we choose&lt;br /&gt;  // the console-based UI here.&lt;br /&gt;&lt;br /&gt;  r.add(&lt;br /&gt;    r.type&amp;lt;StockQuoteApp&amp;gt;()&lt;br /&gt;    .in_scope&amp;lt;di::scopes::singleton&amp;gt;() // The reason we can request a reference in the main function!&lt;br /&gt;    );&lt;br /&gt;&lt;br /&gt;  r.add(&lt;br /&gt;    r.type&amp;lt;UserInterface&amp;gt;()&lt;br /&gt;    .implementation&amp;lt;ConsoleInterface&amp;gt;()&lt;br /&gt;    .in_scope&amp;lt;di::scopes::singleton&amp;gt;()&lt;br /&gt;    );&lt;br /&gt;&lt;br /&gt;  r.add(&lt;br /&gt;    r.type&amp;lt;StockQuoteServiceFactory&amp;gt;()&lt;br /&gt;    .implementation&amp;lt;StaticStockQuoteServiceFactory&amp;gt;()&lt;br /&gt;    .in_scope&amp;lt;di::scopes::singleton&amp;gt;()&lt;br /&gt;    );&lt;br /&gt;&lt;br /&gt;  r.add(&lt;br /&gt;    r.type&amp;lt;HttpDownloadService&amp;gt;()&lt;br /&gt;    .implementation&amp;lt;AsioHttpDownloadService&amp;gt;()&lt;br /&gt;    );&lt;br /&gt;&lt;br /&gt;  r.add(&lt;br /&gt;    r.type&amp;lt;boost::asio::io_service&amp;gt;()&lt;br /&gt;    .in_scope&amp;lt;di::scopes::singleton&amp;gt;()&lt;br /&gt;    );&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p style="clear: both"&gt;As you can see, the mini-DSL (&lt;a href="https://bitbucket.org/cheez/dicpp/src/f35b101eff14/include/di/detail/registration_builder.hpp" target="_blank"&gt;ugly, ugly, ugly, details&lt;/a&gt;) describes a few things:&lt;/p&gt;&lt;ul style="clear: both"&gt;&lt;li&gt;Default implementations for various interface classes. See UserInterface and ConsoleInterface, for example.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Life-cycle management. Singleton is mostly used here but you can also have HTTP-session scopes, thread-local scopes or no scopes (as in HttpDownloadService).&lt;/li&gt;&lt;/ul&gt;&lt;p style="clear: both"&gt;What this means is wherever a type T with a DI_CONSTRUCTOR macro is registered, the registry will use these rules described by the DSL to construct any arguments to T.&lt;/p&gt;&lt;p style="clear: both"&gt;&lt;strong&gt;Providers&lt;/strong&gt;&lt;br /&gt;In this library, there is a concept of a type called a provider whose sole responsibility it is to construct objects (usually within the constraints of a scope). In the app session above, I pointed out how the HTTP download service is not instantiated until it is actually needed. This is done via a provider. You can see the &lt;a href="https://bitbucket.org/cheez/dicpp/src/f35b101eff14/lib/examples/stockquote/YahooStockQuoteService.hpp" target="_blank"&gt;YahooStockQuoteService&lt;/a&gt; has a constructor which accepts a provider and a &lt;a href="https://bitbucket.org/cheez/dicpp/src/f35b101eff14/lib/examples/stockquote/YahooStockQuoteService.cpp" target="_blank"&gt;function&lt;/a&gt; which makes use of it.&lt;/p&gt;&lt;p style="clear: both"&gt;That should be enough information to peruse the &lt;a href="https://bitbucket.org/cheez/dicpp/src/f35b101eff14/lib/examples/stockquote/" target="_blank"&gt;example&lt;/a&gt; itself. Check the &lt;a href="https://bitbucket.org/cheez/dicpp/src/f35b101eff14/lib/examples/stockquote/README" target="_blank"&gt;README&lt;/a&gt; as there are a couple of interesting exercises you can try.&lt;/p&gt;&lt;p style="clear: both"&gt;By the way, this requires a Boost checkout with a built version of Boost Build. I apologize if you can't get it to build on checkout, but I haven't really focused on having other people use it!&lt;/p&gt;&lt;p style="clear: both"&gt;Comments and thoughts welcome.&lt;/p&gt;&lt;br class='final-break' style='clear: both' /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-4974156190839098977?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/b6v1t_6V5do" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/b6v1t_6V5do/deconstructing-dependency-injection.html</link><author>noreply@blogger.com (Sohail Somani)</author><thr:total>0</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2011/04/deconstructing-dependency-injection.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-8581683943365557418</guid><pubDate>Tue, 29 Mar 2011 15:55:00 +0000</pubDate><atom:updated>2011-03-29T11:55:19.075-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">c++</category><category domain="http://www.blogger.com/atom/ns#">clang</category><category domain="http://www.blogger.com/atom/ns#">boost</category><title>C++ has not jumped the shark</title><description>&lt;p style="clear: both"&gt;I love &lt;a href="http://www.johndcook.com/" target="_blank"&gt;John's blog&lt;/a&gt;. If you are not subscribed, you should be subscribed. He is one of my favourite bloggers as I actually learn something when he posts.&lt;/p&gt;&lt;p style="clear: both"&gt;Somehow, I managed to miss his post on &lt;a href="http://www.johndcook.com/blog/2009/08/18/has-cpp-jumped-the-shark/" target="_blank"&gt;C++ going about as far as it can go&lt;/a&gt; in its evolution. Fortunately, it showed up on YCombinator News a few days back so I got the chance to catch up.&lt;/p&gt;&lt;p style="clear: both"&gt;From my reading, John is concerned about the following:&lt;/p&gt;&lt;ul style="clear: both"&gt;&lt;li&gt;The language has stopped evolving because it is too long between revisions of the standard.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;He doesn't need anything new therefore new features are not useful for him.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Something about concepts.&lt;/li&gt;&lt;/ul&gt;&lt;p style="clear: both"&gt; I don't intend on refuting or accepting those points as that's not what this is about. I just wanted to give a short summary. Also, I'm not really that interested in concepts but that is no reason to not include them. I'm sure I would also have said "TEMPLATES? WHY DO WE NEED THIS COMPLEXITY?!!!!"&lt;/p&gt;&lt;p style="clear: both"&gt;The current C++ standard has been greatly influenced by the various &lt;a href="http://www.boost.org/" target="_blank"&gt;Boost&lt;/a&gt; libraries. From lambda to thread, the influence of the Boost development experience is obvious, if not prevalent. Boost made it easy to decide what libraries to include. After all, we've had a few years of practical experience with them.&lt;/p&gt;&lt;p style="clear: both"&gt;Reading the list of libraries in &lt;a href="http://www.boost.org/doc/libs/1_46_1/?sort=boost-version" title="" target="_blank"&gt;first-released order&lt;/a&gt;, there are a lot of libraries for various holes in the standard library. The &lt;a href="http://en.wikipedia.org/wiki/Boost_C%2B%2B_Libraries#Overview" target="_blank"&gt;Wikipedia article&lt;/a&gt; on the Boost libraries makes it much more clear as to where Boost development has been focused.&lt;/p&gt;&lt;p style="clear: both"&gt;There is another trend: the number of libraries dealing with language issues has steadily decreased over time. Now, that is not to say that there will not be another set of C++0B libraries, there probably will. But I don't know if it will trigger the same kind of innovation.&lt;/p&gt;&lt;p style="clear: both"&gt;So if that is all true, is C++ over?&lt;/p&gt;&lt;p style="clear: both"&gt;In the last few years, there has been a gigantic evolution in C++-land: &lt;a href="http://clang.llvm.org/" target="_blank"&gt;Clang&lt;/a&gt;. I have been fortunate enough to spend some quality time with Clang in the last little while and I have to say that I have enjoyed it a lot more than the last time I spent some time with another open-source C++ compiler.&lt;/p&gt;&lt;p style="clear: both"&gt;With Clang, it is reasonably easy to add new features, even easier to add features that translate into combinations of existing features.&lt;/p&gt;&lt;p style="clear: both"&gt;So while it was straightforward to add library changes to C++0B due to Boost, it was a lot harder to do the same for language syntax because there was no real experience with many of the proposed features.&lt;/p&gt;&lt;p style="clear: both"&gt;Clang can enable, for the language, what Boost enabled for libraries.&lt;/p&gt;&lt;p style="clear: both"&gt;However, I don't think Clang is really at the point from an organizational and technical perspective where it can enable and manage the kind of innovation that Boost was able to oversee.&lt;/p&gt;&lt;p style="clear: both"&gt;That being said, I look forward to its role in the future of C++. I think it's a bright one*.&lt;/p&gt;&lt;p style="clear: both"&gt;* Someone please make C++0B lambda polymorphic.&lt;/p&gt;&lt;br class='final-break' style='clear: both' /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-8581683943365557418?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/7BFoiVueaPQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/7BFoiVueaPQ/c-has-not-jumped-shark.html</link><author>noreply@blogger.com (Sohail Somani)</author><thr:total>0</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2011/03/c-has-not-jumped-shark.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-1263078223717033205</guid><pubDate>Sun, 15 Aug 2010 18:32:00 +0000</pubDate><atom:updated>2010-08-16T01:13:28.625-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">development</category><category domain="http://www.blogger.com/atom/ns#">testing</category><category domain="http://www.blogger.com/atom/ns#">emacs</category><title>Continuous testing with Emacs</title><description>&lt;p style="clear: both"&gt;The other day, I came across a very interesting paper on &lt;a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.68.2143&amp;amp;rep=rep1&amp;amp;type=pdf" target="_blank"&gt;continuous testing during development&lt;/a&gt;. In it, the authors found that program correctness for a group of students could be predicted based on whether the students used continuous or manual testing. Continuous testing is running your compilation and project tests as you save files locally, as opposed to continuous integration which usually works as you check in code. Manual testing is having the student run the test suite manually. Those students who used continuous testing were a few times more likely to finish the project and had less mistakes.&lt;/p&gt;&lt;p style="clear: both"&gt;&lt;/p&gt;&lt;p style="clear: both"&gt;&lt;div&gt;There is nothing in Emacs preventing a developer for implementing this behaviour for their projects so I decided to do that to simplify the edit-test cycle for a particular project.&lt;/div&gt;&lt;/p&gt;&lt;p style="clear: both"&gt;&lt;/p&gt;&lt;p style="clear: both"&gt;The key is that after saving a file, using the built-in Emacs hooks, I launch a compile process. The hook only does so if the file being saved is located in the project directory by looking for a string in the filename, "tmp" in this case.&lt;/p&gt;&lt;p style="clear: both"&gt;Here is a &lt;a href="http://www.screencast.com/users/sohails/folders/Jing/media/2943171e-beaf-49c0-9dc2-4407e54474dc" target="_blank"&gt;screencast&lt;/a&gt; of the behaviour with the code in the left side of the split. In the right split, I am editing a script (/tmp/runtest) which represents the test suite. The "project" is located in /tmp. The video shows me saving the test suite file twice. Once with no errors and the second time with an error. In the first case, the compilation buffer goes away once the test suite has run, which keeps things tidy. In the second case, the compilation buffer stays around because an error occurred in the "test suite".&lt;/p&gt;&lt;p style="clear: both"&gt;This specific setup works best with a compilation and test phase which runs relatively fast. To make it work for longer test suites, you'd need to probably modify the test-command code to kill the compilation first. You'd probably also want to modify the after-save-hook to use some kind of timer after which you start the compile.&lt;/p&gt;&lt;p style="clear: both"&gt;There are lots of things which I'd like to work better, but it works OK for me now.&lt;/p&gt;&lt;p style="clear: both"&gt;Let me know how it works out for you if you try it out. The code is &lt;a href="http://paste.lisp.org/display/113548" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p style="clear: both"&gt;Enjoy!&lt;/p&gt;&lt;p style="clear: both"&gt;&lt;/p&gt;&lt;br class='final-break' style='clear: both' /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-1263078223717033205?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/UOPQxazk1Hs" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/UOPQxazk1Hs/continuous-testing-with-emacs.html</link><author>noreply@blogger.com (Sohail Somani)</author><thr:total>0</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2010/08/continuous-testing-with-emacs.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-9144342528911325769</guid><pubDate>Sat, 22 May 2010 18:22:00 +0000</pubDate><atom:updated>2010-06-27T10:48:31.846-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">research</category><title>Dependency Injection in C++/Plugin-based C++ applications</title><description>&lt;p style="clear: both"&gt;I have made two of my coding research projects available on bitbucket. One is an example of writing a C++ application which can dynamically load and execute Python plugins and the other is an investigation into a Google Guice inspired dependency injection library in C++.&lt;/p&gt;&lt;p style="clear: both"&gt;See the wikis for some explanation and browse the code. The code is under WTFPL.&lt;/p&gt;&lt;p style="clear: both"&gt;&lt;div&gt;&lt;ul style="clear: both"&gt;&lt;li&gt;&lt;a href="http://bitbucket.org/cheez/plugins/wiki/Home" title="" target="_blank"&gt;plugins&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://bitbucket.org/cheez/dicpp/wiki/Home" title="" target="_blank"&gt;dicpp&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;If you're wondering, I chose Mercurial because I do not have the brain capacity to understand Git.&lt;/div&gt;&lt;/div&gt;&lt;/p&gt;&lt;p style="clear: both"&gt;&lt;/p&gt;&lt;br class='final-break' style='clear: both' /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-9144342528911325769?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/IDdwNoVT1Fw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/IDdwNoVT1Fw/dependency-injection-in-cplugin-based-c.html</link><author>noreply@blogger.com (Sohail Somani)</author><thr:total>2</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2010/05/dependency-injection-in-cplugin-based-c.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-7012983878207196610</guid><pubDate>Mon, 21 Dec 2009 01:13:00 +0000</pubDate><atom:updated>2009-12-21T11:59:25.796-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">c++</category><category domain="http://www.blogger.com/atom/ns#">scons</category><category domain="http://www.blogger.com/atom/ns#">bjam</category><category domain="http://www.blogger.com/atom/ns#">build</category><title>Using Boost Build on your own projects</title><description>While I am a fan of &lt;a href="http://www.scons.org/"&gt;SCons&lt;/a&gt;, every now and then I like to dabble in other build systems. One that has intrigued me for some time is &lt;a href="http://www.boost.org/doc/tools/build/index.html"&gt;Boost Build&lt;/a&gt; (BB). You can visit the linked site to find out more about it but in a nutshell, it is a very elegant way to build C++ software.&lt;br /&gt;&lt;br /&gt;This post will attempt to give you some steps you can use to get started using the tool on your own projects. Note that it is a bit long but if you are new to Boost Jam as I was a few weeks back, I think it might help you get started. Please feel free to ask any clarifying questions in the comments.&lt;br /&gt;&lt;br /&gt;In the following Boost Jam is the build tool and Boost Build is the library on top of the Jam language. I use them interchangeably, and I'm sure people will give me hell for it.&lt;br /&gt;&lt;h2&gt;Building Boost Jam&lt;/h2&gt;&lt;br /&gt;Before getting started, I suggest you build Boost Jam as follows (might as well get Boost too!). I assume you are on a Unix system &lt;s&gt;because there really is no reason to use Windows anymore ;-)&lt;/s&gt; but you should be able to get the same results on Windows with some slight modifications.&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;$ wget http://downloads.sourceforge.net/project/boost/boost/1.41.0/boost_1_41_0.tar.bz2&lt;br /&gt;$ tar -xjf boost_1_41_0.tar.bz2&lt;br /&gt;$ pushd boost_1_41_0&lt;br /&gt;$ export BOOST_ROOT=$PWD&lt;br /&gt;$ pushd tools/jam/src/&lt;br /&gt;$ ./build.sh&lt;br /&gt;$ export PATH=$PWD/bin.macosxx86:$PATH # substitute appropriately&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Now, when you type "bjam" at the command prompt, you may get the following output:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;$ bjam&lt;br /&gt;warning: No toolsets are configured.&lt;br /&gt;warning: Configuring default toolset "gcc".&lt;br /&gt;warning: If the default is wrong, your build may not work correctly.&lt;br /&gt;warning: Use the "toolset=xxxxx" option to override our guess.&lt;br /&gt;warning: For more configuration options, please consult&lt;br /&gt;warning: http://boost.org/boost-build2/doc/html/bbv2/advanced/configuration.html&lt;br /&gt;&lt;br /&gt;error: error: no Jamfile in current directory found, and no target references specified.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;h2&gt;The Jam Language&lt;/h2&gt;&lt;br /&gt;One complaint about Boost Build is that we must use the Jam language. However, it's really not so bad. While I would prefer Python, the Jam language is consistent and very simple. The main things to remember (this is my mental model and may not be technically accurate):&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;Rules are the same as functions in other languages&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Parameters to functions are separated by ":"&lt;/li&gt;&lt;br /&gt; &lt;li&gt;All tokens are white space separated (use quotes to embed white space)&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Results of functions can be used by enclosing the function call in a [] pair&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Comments start with # and go to the end of the line&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Here is an extremely simple example of a rule/function (create a file called "Jamroot" in the current directory and put in the following):&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;rule show-list ( list-of-stuff + : sep ) #1&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for local l in $(list-of-stuff) #2&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;echo $(l) $(sep) ; #3&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return "Hello, World" ;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;echo [ show-list 1 2 3 : "|" ] ; #4&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;  &lt;li&gt;This line declares a new rule called "show-list" which accepts two parameters: a list as the first parameter and a single value as the second. Note the "+" modifier on the first parameter. This indicates to the build tool that at least one parameter is expected. You can use "*" to indicate 0 or more. I believe this can also be used to indicate optional parameters &lt;/li&gt;&lt;br /&gt;  &lt;li&gt;This line is a for loop using a local variable. Note the variable expansion using the "$()" syntax. In this case, each iteration of the loop will expand to an element of the list in list-of-stuff.&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Here we call the echo rule. Note that the line is terminated by the ";" symbol. This is required!&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Finally, we call the new rule with a list as the first parameter and a keyword enclosed in quotes as the second parameter. We use the result of that rule and pass it to echo.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;If you execute "bjam", the output looks something like:&lt;br /&gt;&lt;verbatim&gt;&lt;br /&gt;1 |&lt;br /&gt;2 |&lt;br /&gt;3 |&lt;br /&gt;Hello, World&lt;br /&gt;&lt;/verbatim&gt;&lt;br /&gt;Pretty boring!&lt;br /&gt;&lt;h2&gt;Creating a new project&lt;/h2&gt;&lt;br /&gt;When Boost Jam is invoked, it looks for a file called "Jamroot" in the current directory or in one of the parents of the current directory. This is where you define project global settings. Let's do that now. Create a new file called Jamroot and include the following contents:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;import toolset ;&lt;br /&gt;&lt;br /&gt;project app&lt;br /&gt;&amp;nbsp;&amp;nbsp;: requirements&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;threading&amp;gt;multi&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;link&amp;gt;static&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;warnings&amp;gt;all&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;warnings-as-errors&amp;gt;on&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;# Equivalent to &amp;lt;toolset&amp;gt;darwin: &amp;lt;architecture&amp;gt;x86 &amp;lt;toolset&amp;gt;darwin: &amp;lt;address-model&amp;gt;32&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[ conditional &amp;lt;toolset&amp;gt;darwin: &amp;lt;architecture&amp;gt;x86 &amp;lt;address-model&amp;gt;32 ]&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;: default-build debug release&lt;br /&gt;&amp;nbsp;&amp;nbsp;: build-dir build&lt;br /&gt; ;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;The requirements state that all artifacts should be built using multi-threaded libraries, built statically with all warnings and all errors. Additionally, on darwin, we only want to build 32-bit executables for the x86 architecture.&lt;br /&gt;&lt;br /&gt;In the default build (when you type just bjam), both debug and release variants will be built and put into the build directory relative to the Jamroot.&lt;br /&gt;&lt;br /&gt;Now, type "bjam". If you are on OSX, you may see something like the following:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;$ bjam&lt;br /&gt;warning: No toolsets are configured.&lt;br /&gt;warning: Configuring default toolset "gcc".&lt;br /&gt;warning: If the default is wrong, your build may not work correctly.&lt;br /&gt;warning: Use the "toolset=xxxxx" option to override our guess.&lt;br /&gt;warning: For more configuration options, please consult&lt;br /&gt;warning: http://boost.org/boost-build2/doc/html/bbv2/advanced/configuration.html&lt;br /&gt;...found 1 target...&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;The reason for this is that BB guesses the toolset but on OSX we should  really be using the darwin toolset. When Boost Jam starts up, it looks at ~/user-config.jam (somewhere similar on Windows) for a user configuration file. Add one with the following contents:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;# ~/user-config.jam&lt;br /&gt;using darwin ;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Now when you hit bjam, you should see something like:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;$ bjam&lt;br /&gt;...found 1 target...&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Alternatively, if you don't want to pollute your file system, you can execute:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;$ bjam toolset=darwin&lt;br /&gt;...found 1 target...&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;h2&gt;Adding a project target&lt;/h2&gt;&lt;br /&gt;Now we will add a simple executable that links to some Boost libraries. Create a directory named "app" in your current directory and create a file in this directory named "Jamfile" with the following contents:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;# app/Jamfile&lt;br /&gt;exe app : [ glob *.cpp ] ;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Additionally, create a C++ file in the app directory with a trivial main function and the ".cpp" extension. Execute bjam. Nothing changed! That's because we haven't asked BJam to build our project. Try executing "bjam app". You should see something like the following:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;$ bjam toolset=darwin app&lt;br /&gt;...found 20 targets...&lt;br /&gt;...updating 17 targets...&lt;br /&gt;common.mkdir build&lt;br /&gt;common.mkdir build/app&lt;br /&gt;common.mkdir build/app/darwin-4.0.1&lt;br /&gt;....&lt;br /&gt;darwin.compile.c++ build/app/darwin-4.0.1/debug/address-model-32/architecture-x86/link-static/threading-multi/main.o&lt;br /&gt;darwin.link build/app/darwin-4.0.1/debug/address-model-32/architecture-x86/link-static/threading-multi/app&lt;br /&gt;common.mkdir build/app/darwin-4.0.1/release&lt;br /&gt;...&lt;br /&gt;darwin.compile.c++ build/app/darwin-4.0.1/release/address-model-32/architecture-x86/link-static/threading-multi/main.o&lt;br /&gt;darwin.link build/app/darwin-4.0.1/release/address-model-32/architecture-x86/link-static/threading-multi/app&lt;br /&gt;...updated 17 targets...&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Note that both debug and release builds were created with one invocation. To restrict to one or the other, execute "bjam variant=debug" or "bjam variant=release".&lt;br /&gt;&lt;h2&gt;Using Boost&lt;/h2&gt;&lt;br /&gt;Remember when we downloaded Boost? Now we will use it! The mechanism for using another Boost Jam project is the "use-project" rule. Add the following to your Jamroot file:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;use-project /boost : ../boost_1_41_0 ;&lt;br /&gt;alias boost_thread&lt;br /&gt;&amp;nbsp;&amp;nbsp;: /boost/thread//boost_thread&lt;br /&gt;&amp;nbsp;&amp;nbsp;: &amp;lt;warnings-as-errors&amp;gt;&gt;off # bunch of warnings&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Here we told the build system where the project with the id "/boost" is located. In this case, it is ../boost_1_41_0, relative to the Jamroot file. Yours might be different. Additionally, we added an alias for the Boost thread library. The main reason for this is that a single alias reduces proliferation of any special handling needed.&lt;br /&gt;&lt;br /&gt;If you type "bjam" now, you will not be surprised that nothing is being built. Let's fix that now. Add the following to the Jamroot file:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;build-project app ;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Now, whenever you invoke bjam, the app project will always be built. Invoke bjam now. You should notice that Boost thread is not being built. Again, this is not surprising. We aren't using it anywhere! Modify app/Jamfile to look like the following and execute bjam:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;exe app : [ glob *.cpp ] ..//boost_thread ;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;You will notice that Boost thread is being built in the Boost directory. This is not very useful as build artifacts are spread all over your disk. (Un?)Fortunately, there is a hack to making this work. Create a new file at the level of your Jamroot named "boost-build.jam". Fill it with the following contents:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;# Add --build-dir to command line so that boost Jamfiles pick it up and use this directory to build.&lt;br /&gt;&lt;br /&gt;ARGV += --build-dir=build ;&lt;br /&gt;&lt;br /&gt;BOOST_ROOT = vendor/boost ;&lt;br /&gt;BOOST_BUILD = $(BOOST_ROOT)/tools/build/v2 ;&lt;br /&gt;boost-build $(BOOST_BUILD) ;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Boost Build looks for this file when building Boost (I think) so here we add the --build-dir parameter so that when building boost, it will build to our build directory. That's a lotta building ;-)&lt;br /&gt;&lt;br /&gt;Hit "bjam" now. You should see Boost thread being built statically in the build directory now, in both debug and release variants.&lt;br /&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;In this post, you learned how to build Boost Jam, a little bit about the Jam language and created a simple project utilizing the Boost libraries. Next time, I will build on this post to cover making a plugin-aware C++ application (this is really quite exciting for me!) Again, if you have any question or comments, feel free to leave them below.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-7012983878207196610?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/IWaZWBvGXxI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/IWaZWBvGXxI/using-boost-build-on-your-own-projects.html</link><author>noreply@blogger.com (Sohail Somani)</author><thr:total>4</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2009/12/using-boost-build-on-your-own-projects.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-8456335778331917180</guid><pubDate>Sun, 29 Nov 2009 20:37:00 +0000</pubDate><atom:updated>2009-11-29T16:27:27.767-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">soapbox</category><category domain="http://www.blogger.com/atom/ns#">quit</category><category domain="http://www.blogger.com/atom/ns#">software</category><category domain="http://www.blogger.com/atom/ns#">notaloser</category><category domain="http://www.blogger.com/atom/ns#">30day</category><title>Knowing when to quit</title><description>"Crossing the Chasm" and "The Dip" are both great books which talk about a distinguishable lag between when early adopters and the bulk of your target market start paying attention to you, financially anyway.&lt;br /&gt;&lt;br /&gt;There is a problem though: a failure and such a chasm look exactly the same for a fairly long time.&lt;br /&gt;&lt;br /&gt;I think a second problem which I'm not sure any book really addresses is that some think they are in a dip when in fact they never entered a dip to begin with. That is why you hear things like "You can't give up now, you made $200!" because they assume that every market is infinitely sized and you've just got to keep going!&lt;br /&gt;&lt;br /&gt;I read somewhere that the average annual sales for shareware is $400. Enough of those and the payment processor is doing alright but of course the authors are not. Classic case of middle-man makes the most money in a transaction.&lt;br /&gt;&lt;br /&gt;So if you are one of those $400/year authors and you need to spend more than 2 hours a year on maintenance, I would really think that is a good reason to quit and do something else. You're not going to miss the $400. &lt;span style="font-weight: bold;"&gt;You never entered a dip.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;There is a very popular and  article titled &lt;a href="http://www.gamedev.net/reference/articles/article1950.asp"&gt;Shareware Amateurs vs Shareware Professionals&lt;/a&gt;. I highly recommend a read. Almost as a case-in-point, the author of that article has quit software altogether and is a fairly successful blogger. That is knowing when to quit.&lt;br /&gt;&lt;br /&gt;If you have to quit, which I do advocate in the right circumstances, it does not mean you are giving up. You are just going to keep trying until you hit your mark. And for heaven's sake, don't think of yourself as a failure. A failure is someone who never tries.&lt;br /&gt;&lt;br /&gt;What do you think?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-8456335778331917180?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/jvFrfOaXvCI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/jvFrfOaXvCI/knowing-when-to-quit.html</link><author>noreply@blogger.com (Sohail Somani)</author><thr:total>0</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2009/11/knowing-when-to-quit.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-1037310819205501139</guid><pubDate>Sat, 17 Oct 2009 14:09:00 +0000</pubDate><atom:updated>2009-10-17T11:24:24.991-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">qt</category><title>Using Boost Function with Qt, Part 2.</title><description>[Following up &lt;a href="http://uint32t.blogspot.com/2008/11/using-boost-bind-and-boost-function.html"&gt;this post&lt;/a&gt;]&lt;br /&gt;&lt;br /&gt;&lt;a href="http://uint32t.blogspot.com/2008/11/using-boost-bind-and-boost-function.html?showComment=1255764339129#c1759598075976409702"&gt;Johan asks&lt;/a&gt;:&lt;br /&gt;&lt;dl class="avatar-comment-indent" id="comments-block"&gt;&lt;dd class="comment-body"&gt;&lt;p&gt;please, please post that follow-up. I'm new to Qt and have just run into this problem. While searching the net, I think your solution seems like the best approach!&lt;br /&gt;&lt;/p&gt;&lt;/dd&gt;&lt;/dl&gt;Who am I to deny a seeker of knowledge? Having used this method in a couple of projects now, I think it is fairly sound and easy to maintain. So here goes.&lt;br /&gt;The main problem with the solution outlined in the earlier post was that it could not handle multiple arguments. On that same post, Ken posted &lt;a href="http://paste.lisp.org/display/87422"&gt;his solution&lt;/a&gt; apparently inspired by mine. His solution also handles multiple arguments but does it by implementing qt_metacall, i.e., mimicking moc. This is probably the most scalable solution and I'll probably give it a second look when I need to do this again. The only problem might be requiring exact matches for types but I am not sure how much of an issue this is for code I have written.&lt;br /&gt;&lt;br /&gt;To review, the problem is that we want to use function objects (Boost Bind, Boost Function, etc) as Qt slots because sometimes it is too much work to create stateful slots.&lt;br /&gt;&lt;br /&gt;My solution looked something like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;struct SignalHandler0 : QObject&lt;br /&gt;{&lt;br /&gt;private:&lt;br /&gt;Q_OBJECT&lt;br /&gt;public:&lt;br /&gt;SignalHandler0(QObject * parent,&lt;br /&gt;              boost::function&lt;void(void)&gt; const &amp;amp; f):&lt;br /&gt; QObject(parent), // parent will delete this object when destructed&lt;br /&gt; m_f(f) {}&lt;br /&gt;&lt;br /&gt;public slots:&lt;br /&gt;void&lt;br /&gt;handleSignal()&lt;br /&gt;{&lt;br /&gt; try&lt;br /&gt; {&lt;br /&gt;   m_f();&lt;br /&gt; }&lt;br /&gt; catch(...)&lt;br /&gt; {&lt;br /&gt;   // Cannot throw exceptions from signals.&lt;br /&gt;   ASSERT_BUG_HERE&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;private:&lt;br /&gt;boost::function&lt;void()&gt;&lt;void(void)&gt; m_f;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;bool&lt;br /&gt;connect(QObject * sender, const char * signal,&lt;br /&gt;     boost::function&lt;void(void)&gt;&lt;void()&gt; const &amp;amp; f)&lt;br /&gt;{&lt;br /&gt;return QObject::connect(sender,signal,&lt;br /&gt;                       // Note: Not a leak as sender will delete the handler when destructed&lt;br /&gt;                       new SignalHandler0(sender,f),SLOT(handleSignal()));&lt;br /&gt;}&lt;br /&gt;&lt;/void()&gt;&lt;/void(void)&gt;&lt;/void(void)&gt;&lt;/void()&gt;&lt;/void(void)&gt;&lt;/pre&gt;To extend it to a single argument, we might do:&lt;br /&gt;&lt;pre&gt;struct SignalHandler1 : QObject&lt;br /&gt;{&lt;br /&gt;private:&lt;br /&gt;Q_OBJECT&lt;br /&gt;public:&lt;br /&gt;SignalHandler1(QObject * parent,&lt;br /&gt;              boost::function&lt;void(a)&gt;&lt;void(qstring&gt; const &amp;amp; f):&lt;br /&gt; QObject(parent), // parent will delete this object when destructed&lt;br /&gt; m_f(f) {}&lt;br /&gt;&lt;br /&gt;public slots:&lt;br /&gt;void&lt;br /&gt;handleSignal(QString const &amp;amp; a)&lt;br /&gt;{&lt;br /&gt; try&lt;br /&gt; {&lt;br /&gt;   m_f(a);&lt;br /&gt; }&lt;br /&gt; catch(...)&lt;br /&gt; {&lt;br /&gt;   // Cannot throw exceptions from signals.&lt;br /&gt;   ASSERT_BUG_HERE&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;private:&lt;br /&gt;boost::function&lt;void(a)&gt;&lt;void(qstring&gt; m_f;&lt;br /&gt;};&lt;br /&gt;&lt;/void(qstring&gt;&lt;/void(a)&gt;&lt;/void(qstring&gt;&lt;/void(a)&gt;&lt;/pre&gt;&lt;br /&gt;That is, create a new class with the right signature. So you might think: well that screams for class templates! Unfortunately, Qt does not support class templates. Doh.&lt;br /&gt;&lt;br /&gt;So basically, we write it out:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;struct SignalHandler : public QObject&lt;br /&gt;{&lt;br /&gt;template&lt;typename&gt;&lt;typename signature=""&gt;&lt;br /&gt;SignalHandler(QObject * parent,boost::function&lt;signature&gt;&lt;signature&gt; f):&lt;br /&gt; QObject(parent),&lt;br /&gt; m_handler(new SignalHandlerImpl&lt;signature&gt;(f))&lt;br /&gt;{}&lt;br /&gt;&lt;br /&gt;struct SignalHandlerBase&lt;br /&gt;{&lt;br /&gt; virtual ~SignalHandlerBase();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;template &lt;typename&gt;&lt;typename signature=""&gt;&lt;br /&gt;struct SignalHandlerImpl&lt;br /&gt;{&lt;br /&gt; SignalHandlerImpl(boost::function&lt;signature&gt;&lt;signature&gt; f):m_f(f){}&lt;br /&gt; boost::function&lt;signature&gt;&lt;signature&gt; f;&lt;br /&gt;}&lt;br /&gt;public slots:&lt;br /&gt;void handleSignal(void);&lt;br /&gt;void handleSignal(QString const &amp;amp;);&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;private:&lt;br /&gt;shared_ptr&lt;signalhandlerbase&gt; m_handler;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;void&lt;br /&gt;SignalHandler::handleSignal(void)&lt;br /&gt;{&lt;br /&gt;typename SignalHandlerImpl&lt;void(void)&gt; type;&lt;br /&gt;type* handler = dynamic_cast&lt;type*&gt;;(m_handler.get());&lt;br /&gt;ASSERT(handler);&lt;br /&gt;handler-&gt;f();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void&lt;br /&gt;SignalHandler::handleSignal(QString const &amp;amp; a)&lt;br /&gt;{&lt;br /&gt;typename SignalHandlerImpl&lt;void(qstring&gt; type;&lt;br /&gt;type* handler = dynamic_cast&lt;type*&gt;(m_handler.get());&lt;br /&gt;ASSERT(handler);&lt;br /&gt;handler-&gt;f(a);&lt;br /&gt;}&lt;br /&gt;&lt;/type*&gt;&lt;/void(qstring&gt;&lt;/type*&gt;&lt;/void(void)&gt;&lt;/signalhandlerbase&gt;&lt;/signature&gt;&lt;/signature&gt;&lt;span style="font-family:Georgia,serif;"&gt;&lt;br /&gt;You can use macros to generate these handlers. You will also need overloaded connect() functions:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;template&lt;typename signature=""&gt;&lt;typename&gt;&lt;br /&gt;QObject*&lt;br /&gt;connect(QObject * sender,&lt;br /&gt;     const char * signal,&lt;br /&gt;     boost::function&lt;signature&gt;&lt;signature&gt; slot);&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;template&lt;&gt;&lt;br /&gt;QObject*&lt;br /&gt;connect&lt;void(void)&gt;&lt;void(void)&gt;(QObject * sender,&lt;br /&gt;                  const char * signal,&lt;br /&gt;                  boost::function&lt;void(void)&gt;&lt;void(void)&gt; slot);&lt;br /&gt;&lt;br /&gt;template&lt;&gt;&lt;br /&gt;QObject*&lt;br /&gt;connect&lt;void(qstring&gt;&lt;void(qstring&gt;(QObject * sender,&lt;br /&gt;                            const char * signal,&lt;br /&gt;                            boost::function&lt;void(qstring&gt;&lt;void(qstring&gt; slot);&lt;br /&gt;&lt;/void(qstring&gt;&lt;/void(qstring&gt;&lt;/void(qstring&gt;&lt;/void(qstring&gt;&lt;/void(void)&gt;&lt;/void(void)&gt;&lt;/void(void)&gt;&lt;/void(void)&gt;&lt;/signature&gt;&lt;/signature&gt;&lt;/typename&gt;&lt;/typename&gt;&lt;/signature&gt;&lt;/signature&gt;&lt;/typename&gt;&lt;/typename&gt;&lt;/signature&gt;&lt;/signature&gt;&lt;/signature&gt;&lt;/typename&gt;&lt;/typename&gt;&lt;/pre&gt;Again, you can use macros.&lt;br /&gt;&lt;br /&gt;I prefer Ken's solution from a technical standpoint. It is a good evolution. The main advantage of his solution is that the amount of code you need to add scales linearly with the number of arguments you need to handle whereas with my solution, they scale with the number of signals and that there are no macros.&lt;br /&gt;&lt;br /&gt;The main advantage of my solution is that it is simpler to understand and maintain, which might be worth the extra code.&lt;br /&gt;&lt;br /&gt;Hope that helps!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-1037310819205501139?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/O4RpuMQqobI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/O4RpuMQqobI/using-boost-function-with-qt-part-2.html</link><author>noreply@blogger.com (Sohail Somani)</author><thr:total>3</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2009/10/using-boost-function-with-qt-part-2.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-3503919203351431488</guid><pubDate>Wed, 19 Aug 2009 05:04:00 +0000</pubDate><atom:updated>2009-08-19T01:17:29.119-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">money</category><title>The best market is one with lots of money</title><description>There are always people who feel that developing plug-ins is not a profitable market. Now while developing a plug-in may not make you as rich as Bill Gates, if there is a sizable market, you will make money.&lt;br /&gt;&lt;br /&gt;So if you are looking for whether your idea makes sense, here is a simple relation to figure it out:&lt;br /&gt;&lt;br /&gt;UnitPrice * NumberOfQualifiedCustomers * ConversionRate &gt;= SomeSpecificFinancialGoal&lt;br /&gt;&lt;br /&gt;If the statement is true, you will make money. If it is not, you will fail.&lt;br /&gt;&lt;br /&gt;I'm pretty sure that I grossly over estimated NumberOfQualifiedCustomers when creating &lt;a href="http://worklogassistant.com"&gt;Worklog Assistant&lt;/a&gt;. How did I over calculate? Simply, the number of total JIRA users who also use JIRA as a timesheet system is quite small (yeah, duh right?) I would not have known this if I did not reach market quickly.&lt;br /&gt;&lt;br /&gt;However, I used very pessimistic values for ConversionRate so maybe that balanced it out because I still reached my financial goals.&lt;br /&gt;&lt;br /&gt;What does this mean for me? It means V2 is going to kick some serious ass. Oh how I wish I could have people to work on this with me, wink wink :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-3503919203351431488?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/nF1fl5ivYW8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/nF1fl5ivYW8/best-market-is-one-with-lots-of-money.html</link><author>noreply@blogger.com (Sohail Somani)</author><thr:total>0</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2009/08/best-market-is-one-with-lots-of-money.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-8779086434072392022</guid><pubDate>Thu, 09 Jul 2009 21:12:00 +0000</pubDate><atom:updated>2009-07-22T01:39:34.706-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">dontreadme</category><category domain="http://www.blogger.com/atom/ns#">bzr</category><category domain="http://www.blogger.com/atom/ns#">futurereference</category><category domain="http://www.blogger.com/atom/ns#">afk</category><title>Going AFK with Bazaar</title><description>One thing I've really liked about distributed VC systems is that they handle merging really well. Of course, this is not limited to DVCSs. Subversion and Perforce have very good merging but do not support offline work very well.&lt;br /&gt;&lt;br /&gt;I've been using Bazaar for a little while now for &lt;a href="http://worklogassistant.com/"&gt;my app&lt;/a&gt; because I knew that I would need to be offline every now and then. I just had one of those periods and thought it would be a great chance to see how well AFK mode works with Bazaar.&lt;br /&gt;&lt;br /&gt;This is more for my own future reference rather than for you :-)&lt;br /&gt;&lt;br /&gt;laptop $ rsync -avz -e ssh sohail@desktop:/home/sohail/bzr/ ~/bzr&lt;br /&gt;laptop $ bzr branch ~/bzr/code/master project&lt;br /&gt;laptop $ bzr bind ~/bzr/code/master&lt;br /&gt;&lt;br /&gt;Now I can work offline in the "project" directory and all checkins go to ~/bzr .&lt;br /&gt;&lt;br /&gt;Upon return:&lt;br /&gt;&lt;br /&gt;laptop $ rsync -avz -e ssh ~/bzr/ sohail@desktop:/home/sohail/bzr&lt;br /&gt;&lt;br /&gt;NOTE TRAILING SLASH ON SOURCE DIRECTORY!!!!!1111oneone....&lt;br /&gt;&lt;br /&gt;Note: I think the above is insane. Ideally, I'd just do something like:&lt;br /&gt;&lt;br /&gt;laptop $ bzr checkout bzr+ssh://sohail@desktop/home/sohail/bzr bzr&lt;br /&gt;laptop $ cd bzr&lt;br /&gt;laptop $ bzr work-offline&lt;br /&gt;&lt;br /&gt;Return from afk:&lt;br /&gt;&lt;br /&gt;laptop $ bzr I'm back&lt;br /&gt;&lt;br /&gt;Or something like that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-8779086434072392022?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/BlaMV2FcBIM" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/BlaMV2FcBIM/going-afk-with-bazaar.html</link><author>noreply@blogger.com (Sohail Somani)</author><thr:total>0</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2009/07/going-afk-with-bazaar.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-1161318549264845423</guid><pubDate>Mon, 08 Jun 2009 23:37:00 +0000</pubDate><atom:updated>2009-06-08T19:40:29.128-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">vancpp</category><title>VanCPP June meeting</title><description>If you are in Vancouver and interested in programming (who isn't?!) you might want to make your way to the VanCPP meeting in June. The announcement is below:&lt;br /&gt;      &lt;!--~-|**|PrettyHtmlEnd|**|-~--&gt;       &lt;p&gt;Our June 2009 meeting will be held on Thursday, June 18. Please note the &lt;a href="http://workspacecafe.ca/"&gt;new venue&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Topic: &lt;span style="color:#407f00;"&gt;&lt;b&gt;&lt;span style="font-size:100%;"&gt;Concurrent Programming in the D Programming Language&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Presented by &lt;strong&gt;Walter Bright&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;&lt;b&gt;Abstract&lt;/b&gt;: Many-core concurrent programming offers exciting and compelling advantages. The single core, single thread programming model is assumed by imperative programming languages. This model offers sequential consistency as its fundamental characteristic.&lt;wbr&gt;Because many-core systems use layered cache memory systems,sequential consistency is not guaranteed among threads.Because imperative programming languages allow implicit sharing of data between threads, many misguided idioms and optimizations are possible that erroneously assume sequential consistency.&lt;wbr&gt;One example of this is the double checked locking optimization.&lt;wbr&gt;The pernicious nature of these sorts of bugs is they defy programmers' natural intuition about how programs behave,they are not statically detectable, and there is no way to reliably test a program to rule out the existence of such bugs.A program may appear to work, but have problems appear years later, fail when ported to a different platform, and such problems may be extremely hard to reproduce and track down.In essence, the correctness of the program relies entirely on the expertise and care of the programmer.This is not an acceptable situation for developers of programs that require high reliability.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;The &lt;a href="http://www.digitalmars.com/d/"&gt;D programming language&lt;/a&gt; is an imperative programming language with an innovative type system that prevents implicit sharing and also fosters a complete, integrated pure functional subset. It is possible to statically verify that D programs do not have sequential consistency bugs. The double checked locking optimization bug is not possible. Type support for shared data and immutable data, as well as pure functions, means that mutating data interactions between threads can occur only under carefully controlled conditions.This dramatically reduces the problem space for concurrency bugs from the whole of the source code to a small subset of it, making it a much more tractable problem.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;&lt;strong&gt;Speaker bio:&lt;/strong&gt; &lt;a href="http://www.walterbright.com/"&gt;Walter Bright&lt;/a&gt; graduated from Caltech in 1979 with a degree in mechanical engineering. He worked for Boeing for three years on the development of the 757 stabilizer trim system. He then switched to writing software, in particular compilers, and has been writing them ever since.&lt;/span&gt;&lt;/p&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;The meeting will be held at:&lt;br /&gt;&lt;strong&gt;&lt;a href="http://workspacecafe.ca/"&gt;Workspace&lt;/a&gt;&lt;/strong&gt;&lt;br /&gt;&lt;a href="http://maps.google.com/maps?f=q&amp;amp;source=s_q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=21+water+street,+vancouver,+canada&amp;amp;ie=UTF8&amp;amp;z=16&amp;amp;iwloc=A"&gt;21 Water Street&lt;/a&gt;&lt;br /&gt;Vancouver, BC&lt;br /&gt;V6B 1A&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Regards,&lt;/p&gt;&lt;p&gt;Vladan Vidakovic&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-1161318549264845423?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/eqHpk-lHigY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/eqHpk-lHigY/vancpp-june-meeting.html</link><author>noreply@blogger.com (Sohail Somani)</author><thr:total>0</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2009/06/vancpp-june-meeting.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-7862667418648087530</guid><pubDate>Fri, 08 May 2009 01:26:00 +0000</pubDate><atom:updated>2010-02-06T17:18:47.421-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">c++0x</category><category domain="http://www.blogger.com/atom/ns#">lambda</category><category domain="http://www.blogger.com/atom/ns#">qt</category><category domain="http://www.blogger.com/atom/ns#">wla</category><title>Using C++0x lambda to replace Boost Bind in C++03 code</title><description>[Note: This post looks ugly under Internet Explorer. If you want to tell me how to fix my CSS, that would be much appreciated]&lt;br /&gt;[Note: This post was written using the Intel C++ compiler with -std=c++0x.]&lt;br /&gt;&lt;br /&gt;As some of you know, I work on &lt;a href="http://worklogassistant.com/"&gt;Worklog Assistant&lt;/a&gt; which is written using C++/Qt.&lt;br /&gt;&lt;br /&gt;One thing that I've made very good use of is a slightly modified version of the code in an earlier post titled &lt;a href="http://uint32t.blogspot.com/2008/11/using-boost-bind-and-boost-function.html"&gt;"Using Boost Bind and Boost Function with Qt"&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;As an example, consider the following code from the above app which creates a popup menu to toggle the visibility of table columns. This is done by creating a "toggle" action for each column header that... toggles the visibility. It might help to think how this action would be created in plain Qt (hint: it would be painful.) It would certainly not have the locality it does now.&lt;br /&gt;&lt;pre class="cxx"&gt;&lt;span class="type"&gt;voi&lt;/span&gt;&lt;span class="type"&gt;d&lt;/span&gt;&lt;br /&gt;&lt;span class="function-name"&gt;showColumnHeaderContextMenu&lt;/span&gt;(&lt;span class="constant"&gt;ssci&lt;/span&gt;::&lt;span class="type"&gt;CustomTableView&lt;/span&gt; * &lt;span class="variable-name"&gt;self&lt;/span&gt;,&lt;span class="keyword"&gt;const&lt;/span&gt; &lt;span class="type"&gt;QPoint&lt;/span&gt; &amp;amp; &lt;span class="variable-name"&gt;pos&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;&lt;span class="type"&gt;QMen&lt;/span&gt;&lt;span class="type"&gt;u&lt;/span&gt; &lt;span class="function-name"&gt;columns&lt;/span&gt;(&lt;span class="constant"&gt;ssci&lt;/span&gt;::&lt;span class="constant"&gt;CustomTableView&lt;/span&gt;::tr(&lt;span class="string"&gt;"Visible Columns"&lt;/span&gt;));&lt;br /&gt;columns.setIcon(QIcon(&lt;span class="constant"&gt;QString&lt;/span&gt;::fromLatin1(&lt;span class="string"&gt;":/ui/icons/grid.png"&lt;/span&gt;)));&lt;br /&gt;&lt;br /&gt;QHeaderView * headers(self-&amp;gt;horizontalHeader());&lt;br /&gt;&lt;br /&gt;&lt;span class="constant"&gt;std&lt;/span&gt;::&lt;span class="type"&gt;vector&lt;/span&gt;&amp;lt;&lt;span class="constant"&gt;std&lt;/span&gt;::&lt;span class="type"&gt;pair&lt;/span&gt;&amp;lt;QString,&lt;span class="type"&gt;int&lt;/span&gt;&amp;gt; &amp;gt; &lt;span class="variable-name"&gt;sorted_columns&lt;/span&gt;;&lt;br /&gt;getSortedColumns(self-&amp;gt;model(),headers,sorted_columns);&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;for&lt;/span&gt;(&lt;span class="type"&gt;in&lt;/span&gt;&lt;span class="type"&gt;t&lt;/span&gt; &lt;span class="variable-name"&gt;ii&lt;/span&gt; = 0; ii &amp;lt; headers-&amp;gt;count(); ++ii)&lt;br /&gt;{&lt;br /&gt;&lt;span class="type"&gt;QActio&lt;/span&gt;&lt;span class="type"&gt;n&lt;/span&gt; * &lt;span class="variable-name"&gt;action&lt;/span&gt; =&lt;br /&gt;&lt;span class="keyword"&gt;new&lt;/span&gt; &lt;span class="type"&gt;QAction&lt;/span&gt;(sorted_columns[ii].first,&lt;br /&gt;            &amp;amp;columns);&lt;br /&gt;&lt;br /&gt;&lt;span class="type"&gt;boo&lt;/span&gt;&lt;span class="type"&gt;l&lt;/span&gt; &lt;span class="variable-name"&gt;is_hidden&lt;/span&gt; = headers-&amp;gt;isSectionHidden(sorted_columns[ii].second);&lt;br /&gt;&lt;br /&gt;action-&amp;gt;setCheckable(&lt;span class="constant"&gt;true&lt;/span&gt;);&lt;br /&gt;action-&amp;gt;setChecked(&lt;span class="negation-char"&gt;!&lt;/span&gt;is_hidden);&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; &lt;span class="constant"&gt;boost&lt;/span&gt;::&lt;span class="type"&gt;bin&lt;/span&gt;&lt;span class="type"&gt;d&lt;/span&gt;;&lt;br /&gt;&lt;span class="keyword"&gt;using&lt;/span&gt; &lt;span class="constant"&gt;boost&lt;/span&gt;::&lt;span class="type"&gt;functio&lt;/span&gt;&lt;span class="type"&gt;n&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="type"&gt;function&lt;/span&gt;&amp;lt;&lt;span class="type"&gt;void&lt;/span&gt;()&amp;gt; &lt;span class="variable-name"&gt;toggle&lt;/span&gt; =&lt;br /&gt;bind(&amp;amp;&lt;span class="constant"&gt;QHeaderView&lt;/span&gt;::setSectionHidden,headers,&lt;br /&gt;     sorted_columns[ii].second,&lt;span class="negation-char"&gt;!&lt;/span&gt;is_hidden);&lt;br /&gt;&lt;br /&gt;&lt;span class="constant"&gt;ssci&lt;/span&gt;::connect(action,SIGNAL(triggered()),&lt;br /&gt;            toggle);&lt;br /&gt;&lt;br /&gt;columns.addAction(action);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="type"&gt;QMen&lt;/span&gt;&lt;span class="type"&gt;u&lt;/span&gt; &lt;span class="variable-name"&gt;menu&lt;/span&gt;;&lt;br /&gt;menu.addMenu(&amp;amp;columns);&lt;br /&gt;&lt;br /&gt;menu.exec(self-&amp;gt;mapToGlobal(pos));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Of particular interest is the code in the for loop which sets up the actions:&lt;br /&gt;&lt;pre class="cxx"&gt;    &lt;span class="type"&gt;function&lt;/span&gt;&amp;lt;&lt;span class="type"&gt;void&lt;/span&gt;()&amp;gt; &lt;span class="variable-name"&gt;toggle&lt;/span&gt; =&lt;br /&gt;bind(&amp;amp;&lt;span class="constant"&gt;QHeaderView&lt;/span&gt;::setSectionHidden,headers,&lt;br /&gt;     sorted_columns[ii].second,&lt;span class="negation-char"&gt;!&lt;/span&gt;is_hidden);&lt;br /&gt;&lt;br /&gt;&lt;span class="constant"&gt;ssci&lt;/span&gt;::connect(action,SIGNAL(triggered()),&lt;br /&gt;              toggle);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This creates a function object on the fly which hides the selected column using code from the above linked post. To do this in plain Qt is a gigantic pain. &lt;a href="http://libqxt.org/"&gt;LibQxt&lt;/a&gt; has a solution as well but mine is much better!&lt;br /&gt;&lt;br /&gt;Anyway, the point is that you might find a lot of code using bind and function in an app like this. Binding member function pointers, member data pointers and function pointers is fairly normal and is really the only way to maintain sanity and reduce boiler plate. Nested binds are also used where appropriate.&lt;br /&gt;&lt;br /&gt;Boost Bind is a way to create closures, or at least as close as you can get in C++ to true closures. Therefore it is natural to try and replace some uses of Boost Bind with C++0x lambda. There is good coverage of how C++0x lambda works &lt;a href="http://blogs.msdn.com/vcblog/archive/2008/10/28/lambdas-auto-and-static-assert-c-0x-features-in-vc10-part-1.aspx"&gt;here&lt;/a&gt; so I won't repeat the same information. However, I will cover the cases of bind I could convert and (horrifically) the cases I couldn't!&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Using automatic variables&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Consider the following code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="cxx"&gt;&lt;span class="keyword"&gt;const&lt;/span&gt; &lt;span class="type"&gt;in&lt;/span&gt;&lt;span class="type"&gt;t&lt;/span&gt; &lt;span class="variable-name"&gt;LICENSING_TAB_INDEX&lt;/span&gt; = 1;&lt;br /&gt;&lt;br /&gt;&lt;span class="constant"&gt;ssci&lt;/span&gt;::connect(lblImportNewLicense,SIGNAL(linkActivated(QString &lt;span class="keyword"&gt;const&lt;/span&gt; &amp;amp;)),&lt;br /&gt;            &lt;span class="constant"&gt;boost&lt;/span&gt;::&lt;span class="type"&gt;function&lt;/span&gt;&amp;lt;&lt;span class="type"&gt;void&lt;/span&gt;()&amp;gt;(&lt;br /&gt;              &lt;span class="constant"&gt;boost&lt;/span&gt;::&lt;span class="variable-name"&gt;bind&lt;/span&gt;(&amp;amp;&lt;span class="constant"&gt;QTabWidget&lt;/span&gt;::setCurrentIndex,&lt;br /&gt;                          tabWidget,&lt;br /&gt;                          LICENSING_TAB_INDEX)&lt;br /&gt;              )&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The above function call sets things up so that when a link is clicked in the interface, the &lt;tt&gt;LICENSING_TAB_INDEX&lt;/tt&gt; tab is selected in the configuration.&lt;br /&gt;&lt;br /&gt;One thing Boost Bind does is that it stores all bound arguments by value. That means &lt;tt&gt;&amp;amp;QTabWidget::setCurrentIndex&lt;/tt&gt;, &lt;tt&gt;tabWidget&lt;/tt&gt; and &lt;tt&gt;LICENSING_TAB_INDEX&lt;/tt&gt; are all stored by value. C++0x lambda calls this capturing. This can be done using implicit capture (by parsing the lambda body) or by you. &lt;ss&gt;By default, C++0x lambda captures variables by reference&lt;/ss&gt;. It is potentially buggy to capture function-local variables by reference automatically. Therefore, the above code translated to C++0x lambda is:&lt;br /&gt;&lt;pre class="cxx"&gt;[=]()&lt;br /&gt;{ tabWidget-&amp;gt;setCurrentIndex(LICENSING_TAB_INDEX); }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The first element of a lambda-introducer (the []) can be a capture default which can be one of = or &amp;amp;. The capture default tells the compiler how to capture those variables that are implicitly captured. The assignment is supposed to make you think of copy assignment and the &amp;amp; is supposed to make you think of reference to. So in the above case, to get the exact same behaviour as the bind, we need to intentionally copy all variables by value.&lt;br /&gt;&lt;br /&gt;Great! Not so bad :-)&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;A simpler example... Or is it?&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Consider the following code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="cxx"&gt;&lt;span class="constant"&gt;ssci&lt;/span&gt;::connect(clearSelectedRole,SIGNAL(clicked()),&lt;br /&gt;            &lt;span class="constant"&gt;boost&lt;/span&gt;::&lt;span class="type"&gt;function&lt;/span&gt;&amp;lt;&lt;span class="type"&gt;void&lt;/span&gt;()&amp;gt;(&lt;br /&gt;              &lt;span class="constant"&gt;boost&lt;/span&gt;::&lt;span class="variable-name"&gt;bind&lt;/span&gt;(&lt;br /&gt;                &amp;amp;&lt;span class="constant"&gt;QComboBox&lt;/span&gt;::setCurrentIndex,&lt;br /&gt;                projectRoles,&lt;br /&gt;                -1)&lt;br /&gt;              )&lt;br /&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This code sets things up so that when the &lt;tt&gt;clearSelectedRole&lt;/tt&gt; button is clicked, the corresponding &lt;tt&gt;QComboBox&lt;/tt&gt; has an invalid index.&lt;br /&gt;&lt;br /&gt;The C++0x version of this is really straightforward:&lt;br /&gt;&lt;br /&gt;&lt;pre class="cxx"&gt;&lt;span class="constant"&gt;ssci&lt;/span&gt;::connect(clearSelectedRole,SIGNAL(clicked()),&lt;br /&gt;            &lt;span class="constant"&gt;boost&lt;/span&gt;::&lt;span class="type"&gt;function&lt;/span&gt;&amp;lt;&lt;span class="type"&gt;void&lt;/span&gt;()&amp;gt;(&lt;br /&gt;              [&amp;amp;](){projectRoles-&amp;gt;setCurrentIndex(-1);}&lt;br /&gt;              )&lt;br /&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In this case, the pointer object (not the value) &lt;tt&gt;projectRoles&lt;/tt&gt; is captured by reference. This is not an issue because the pointer object is guaranteed to outlive the closure. Now you know why closures and garbage collection go together :-)&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Verbosity or Why I wish C++0x used polymorphic lambdas&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Consider the following code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="cxx"&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;br /&gt;&lt;span class="type"&gt;voi&lt;/span&gt;&lt;span class="type"&gt;d&lt;/span&gt;&lt;br /&gt;&lt;span class="function-name"&gt;updateThreadSetup&lt;/span&gt;(&lt;span class="type"&gt;QObject&lt;/span&gt; * &lt;span class="variable-name"&gt;parent&lt;/span&gt;,&lt;span class="constant"&gt;ssci&lt;/span&gt;::&lt;span class="type"&gt;MainWindow&lt;/span&gt; * &lt;span class="variable-name"&gt;self&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;m_checkForUpdatesThread(&lt;span class="constant"&gt;boost&lt;/span&gt;::bind(updateThreadSetup,_1,&amp;amp;parent))&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The bound function in this case is an object that calls the function updateThreadSetup with a to-be-determined value for the first parameter and a fixed value for the second parameter.&lt;br /&gt;&lt;br /&gt;The C++0x version of this is horrible:&lt;br /&gt;&lt;pre class="cxx"&gt;m_checkForUpdatesThread([&amp;amp;parent](QObject * obj){updateThreadSetup(obj,&amp;amp;parent);});&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;First, since &lt;tt&gt;parent&lt;/tt&gt; is a local variable (was passed into the function), you can't implicitly capture it. So you have to explicitly capture it. In this case, we want to capture it by reference, hence &lt;tt&gt;[&amp;amp;parent]&lt;/tt&gt; in the lambda-introducer. Then, since this thread setup function is passed in a &lt;tt&gt;QObject*&lt;/tt&gt; we have to tell the compiler to accept this argument. Apparently it isn't smart enough. Ask someone why it is this way, you'll hear some hand waving about the callable concept. Whatever.&lt;br /&gt;&lt;br /&gt;That is some ugly code.&lt;br /&gt;&lt;br /&gt;Anyway...&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;What you cannot convert without making your code super ugly&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;Consider the following simple code:&lt;br /&gt;&lt;pre class="cxx"&gt;&lt;span class="type"&gt;vector&lt;/span&gt;&amp;lt;&lt;span class="type"&gt;int&lt;/span&gt;&amp;gt; &lt;span class="variable-name"&gt;d&lt;/span&gt; = {1,2,3,4,5};&lt;br /&gt;vector&amp;lt;&lt;span class="type"&gt;function&lt;/span&gt;&amp;lt;&lt;span class="type"&gt;int&lt;/span&gt;()&amp;gt;&amp;gt; &lt;span class="variable-name"&gt;funcs&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;for&lt;/span&gt;(&lt;span class="constant"&gt;vector&lt;/span&gt;&amp;lt;&lt;span class="type"&gt;int&lt;/span&gt;&amp;gt;::&lt;span class="type"&gt;iterato&lt;/span&gt;&lt;span class="type"&gt;r&lt;/span&gt; &lt;span class="variable-name"&gt;it&lt;/span&gt; = d.begin(), &lt;span class="variable-name"&gt;end&lt;/span&gt; = d.end();&lt;br /&gt;  it != end;&lt;br /&gt;  ++it)&lt;br /&gt;{&lt;br /&gt;funcs.push_back(&lt;span class="constant"&gt;boost&lt;/span&gt;::bind(add5,*it));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This creates a vector of function objects that presumably add 5 to their bound argument and return the result.&lt;br /&gt;&lt;br /&gt;Here is the equivalent in C++0x lambda:&lt;br /&gt;&lt;br /&gt;&lt;pre class="cxx"&gt;&lt;span class="type"&gt;vector&lt;/span&gt;&amp;lt;&lt;span class="type"&gt;int&lt;/span&gt;&amp;gt; &lt;span class="variable-name"&gt;d&lt;/span&gt; = {1,2,3,4,5};&lt;br /&gt;vector&amp;lt;function&amp;lt;&lt;span class="type"&gt;int&lt;/span&gt;()&amp;gt;&amp;gt; funcs;&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;for&lt;/span&gt;(&lt;span class="constant"&gt;vector&lt;/span&gt;&amp;lt;&lt;span class="type"&gt;int&lt;/span&gt;&amp;gt;::&lt;span class="type"&gt;iterato&lt;/span&gt;&lt;span class="type"&gt;r&lt;/span&gt; &lt;span class="variable-name"&gt;it&lt;/span&gt; = d.begin(), &lt;span class="variable-name"&gt;end&lt;/span&gt; = d.end();&lt;br /&gt;  it != end;&lt;br /&gt;  ++it)&lt;br /&gt;{&lt;br /&gt;&lt;span class="type"&gt;in&lt;/span&gt;&lt;span class="type"&gt;t&lt;/span&gt; &amp;amp;&lt;span class="variable-name"&gt;i&lt;/span&gt; = *it; &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;WTF?&lt;br /&gt;&lt;/span&gt;  funcs.push_back([i](){add5(i);});&lt;span class="comment-delimiter"&gt;//&lt;/span&gt;&lt;span class="comment"&gt;THIS IS REDUNDANT. REDUNDANT.&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Naively, one might have done:&lt;br /&gt;&lt;br /&gt;&lt;pre class="cxx"&gt;funcs.push_back([it](){add5(*it);});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;in the loop. But this is a bug waiting to happen. Add the following line right after the for loop:&lt;br /&gt;&lt;pre class="cxx"&gt;d.push_back(0)&lt;/pre&gt;&lt;br /&gt;Now all those iterators that are captured by value can be invalidated! YAY! The only way to avoid this issue is to manually extract the value referenced by the iterator and pass that into the closure which is what I did in my translation.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;br /&gt;&lt;br /&gt;This exercise showed me that C++0x lambda is of some interest to me. I'd really like to get rid of the verbosity (I know, too late!) A couple of things would make this the perfect lambda for me:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Polymorphic lambdas (or at least let me specify auto for the arguments)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;An easy way to capture computed values (the *it bug above)&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;I don't know how these problems would be solved, or whether they could be but until they are, I think there is still a future for function binding ala Boost Bind which is fine by me!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-7862667418648087530?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/16jDb5QHaUo" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/16jDb5QHaUo/using-c0x-lambda-to-replace-boost-bind.html</link><author>noreply@blogger.com (Sohail Somani)</author><thr:total>7</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2009/05/using-c0x-lambda-to-replace-boost-bind.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-6821142006276838244</guid><pubDate>Mon, 04 May 2009 04:23:00 +0000</pubDate><atom:updated>2009-05-04T00:31:46.297-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">boostcon</category><title>BoostCon 2009</title><description>&lt;a href="http://boostcon.com"&gt;BoostCon&lt;/a&gt; starts tomorrow.&lt;br /&gt;&lt;br /&gt;I went to the first and second Boost conferences. The first as an attendee, the second as a speaker. I was blown away by the quality of the talks, particularly the author's corner series of talks. I think that if the organizers are smart about it, this can be one of the best conferences. For me, it is already on par with conferences like SD West for quality and relevance.&lt;br /&gt;&lt;br /&gt;I am extremely disappointed that I could not make it this year due to my schedule being way too busy. I hope that some of you reading this have been able to schedule better than me and go to BoostCon.&lt;br /&gt;&lt;br /&gt;If you are attending, please ask at least one very difficult on-topic question in each of your talks for me.&lt;br /&gt;&lt;br /&gt;Also, ask &lt;a href="http://www.boost.org/users/people/joel_de_guzman.html"&gt;Joel de Guzman&lt;/a&gt; about Boost.GUI. Apparently he's got something cooking (you didn't hear it from me!)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-6821142006276838244?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/e2ubvd9fevA" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/e2ubvd9fevA/boostcon-2009.html</link><author>noreply@blogger.com (Sohail Somani)</author><thr:total>0</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2009/05/boostcon-2009.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-7231893924325400141</guid><pubDate>Thu, 19 Mar 2009 22:51:00 +0000</pubDate><atom:updated>2009-03-19T18:56:34.894-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">lisp</category><category domain="http://www.blogger.com/atom/ns#">qt</category><title>A seemingly complete Qt API for CL</title><description>Just came across this library called &lt;a href="http://common-lisp.net/project/commonqt/"&gt;CommonQT&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It is more complete than the API I developed earlier. It is also using the KDE Smoke libraries which make it damn easy to create the API on the fly.&lt;br /&gt;&lt;br /&gt;Very exciting.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-7231893924325400141?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/GwLMZ9jn9Ew" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/GwLMZ9jn9Ew/seemingly-complete-qt-api-for-cl.html</link><author>noreply@blogger.com (Sohail Somani)</author><thr:total>2</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2009/03/seemingly-complete-qt-api-for-cl.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-2870197845099753333</guid><pubDate>Sun, 15 Feb 2009 22:01:00 +0000</pubDate><atom:updated>2009-02-15T17:05:55.524-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">broken</category><category domain="http://www.blogger.com/atom/ns#">nvidia</category><category domain="http://www.blogger.com/atom/ns#">ubuntu</category><title>Latest NVIDIA drivers, Ubuntu Edgy</title><description>NVIDIA drivers not loading after the latest Ubuntu update? Low resolution mode?&lt;br /&gt;&lt;br /&gt;They used to work didn't they?&lt;br /&gt;&lt;br /&gt;Before you start uninstalling Ubuntu packages and installing the official NVIDIA drivers, throwing your hands up and generally having a bad day, try this:&lt;br /&gt;&lt;br /&gt;(as root): echo nvidia &gt;&gt; /etc/modules&lt;br /&gt;&lt;br /&gt;Reboot. Should work now.&lt;br /&gt;&lt;br /&gt;For some reason, you need to explicitly load the module with the latest nvidia packages (I'm using nvidia-glx-new)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-2870197845099753333?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/EtTSEzvp1Vg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/EtTSEzvp1Vg/latest-nvidia-drivers-ubuntu-edgy.html</link><author>noreply@blogger.com (Sohail Somani)</author><thr:total>0</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2009/02/latest-nvidia-drivers-ubuntu-edgy.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-3395965405933753573</guid><pubDate>Wed, 14 Jan 2009 08:51:00 +0000</pubDate><atom:updated>2009-01-14T03:52:18.794-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">qt</category><title>Qt goes LGPL!</title><description>http://www.qtsoftware.com/about/news/lgpl-license-option-added-to-qt&lt;br /&gt;&lt;br /&gt;Now that's awesome.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-3395965405933753573?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/Y3CEnJsRUIk" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/Y3CEnJsRUIk/qt-goes-lgpl.html</link><author>noreply@blogger.com (Sohail Somani)</author><thr:total>4</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2009/01/qt-goes-lgpl.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-4183447400014795010</guid><pubDate>Wed, 26 Nov 2008 19:03:00 +0000</pubDate><atom:updated>2008-11-26T19:05:07.155-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">c++</category><category domain="http://www.blogger.com/atom/ns#">qt</category><title>Using Boost Bind and Boost Function with Qt</title><description>One very, very, very annoying feature of Qt in C++ is how very difficult it is to create bespoke slots.&lt;br /&gt;&lt;br /&gt;With &lt;a href="http://gtkmm.org"&gt;gtkmm&lt;/a&gt;, you can more or less get away with using &lt;a href="http://www.boost.org/doc/libs/1_37_0/libs/bind/bind.html"&gt;boost::bind&lt;/a&gt; so long as the bind results in a 0-ary function (otherwise the signal/slots library for gtkmm is not compatible.)&lt;br /&gt;&lt;br /&gt;With Qt, you have to write a new member function, or heaven forbid, a new class. This is too much typing for me. Ideally, what I would like to do is something like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;connect(some_button,SIGNAL(clicked()),&lt;br /&gt;        boost::bind(&amp;Foo::bar,something,else,entirely));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Doing this with bare Qt, I'd have to:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;Create a new slot function: &lt;tt&gt;Foo::bar_special_case&lt;/tt&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Add member variables for the variables &lt;tt&gt;else,entirely&lt;/tt&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Finally use it as: connect(some_button,SIGNAL(clicked(),something,SLOT(bar_special_case()))&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;After doing this for the 100 billionth time, I realized that there should be a better way to do this. After months of investigation, I have discovered that there is no better way to do this.&lt;br /&gt;&lt;br /&gt;Just kidding.&lt;br /&gt;&lt;br /&gt;The idea is to create a slot handler that accepts &lt;a href="http://www.boost.org/doc/libs/1_37_0/doc/html/function.html"&gt;boost::function&lt;/a&gt; types:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;struct SignalHandler0 : QObject&lt;br /&gt;{&lt;br /&gt;private:&lt;br /&gt;  Q_OBJECT&lt;br /&gt;public:&lt;br /&gt;  SignalHandler0(QObject * parent,&lt;br /&gt;                 boost::function&amp;lt;void(void)&amp;gt; const &amp; f):&lt;br /&gt;    QObject(parent), // parent will delete this object when destructed&lt;br /&gt;    m_f(f) {}&lt;br /&gt;&lt;br /&gt;public slots:&lt;br /&gt;  void&lt;br /&gt;  handleSignal()&lt;br /&gt;  {&lt;br /&gt;    try&lt;br /&gt;    { &lt;br /&gt;      m_f();&lt;br /&gt;    }&lt;br /&gt;    catch(...)&lt;br /&gt;    {&lt;br /&gt;      // Cannot throw exceptions from signals.&lt;br /&gt;      ASSERT_BUG_HERE&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;private:&lt;br /&gt;  boost::function&amp;lt;void(void)&amp;gt; m_f;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;If I were to use this class directly, I would write:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;connect(button,SIGNAL(clicked()),&lt;br /&gt;        // Note: Not a leak as button will delete the handler when destructed&lt;br /&gt;        new SignalHandler0(button,boost::bind(&amp;Foo::bar,something,else,entirely)),&lt;br /&gt;        SLOT(handleSignal()));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That's pretty much it. Of course, this is a bit too verbose so I'd write a free function:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;bool&lt;br /&gt;connect(QObject * sender, const char * signal,&lt;br /&gt;        boost::function&lt;void(void)&gt; const &amp; f)&lt;br /&gt;{&lt;br /&gt;  return QObject::connect(sender,signal,&lt;br /&gt;                          // Note: Not a leak as sender will delete the handler when destructed&lt;br /&gt;                          new SignalHandler0(sender,f),SLOT(handleSignal()));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And use it as:&lt;tt&gt;::connect(button,SLOT(clicked()),boost::bind(&amp;Foo::bar,something,else,entirely))&lt;/tt&gt;&lt;br /&gt;&lt;br /&gt;The obvious problem with this approach is if you add any overload of the free function + bind and you are in for some fun. I prototyped a solution for this based on the &lt;a href="http://www.boost.org/doc/libs/1_37_0/libs/function_types/doc/html/index.html"&gt;Boost.FunctionTypes&lt;/a&gt; library but at the moment, I don't need this (i.e., I am happy with 0-ary bind)&lt;br /&gt;&lt;br /&gt;Another thing... Why does the aforementioned function types library not handle boost function and boost bind?&lt;br /&gt;&lt;br /&gt;Odd.&lt;br /&gt;&lt;br /&gt;PS: I'm not dead. I just smell funny.&lt;br /&gt;PPS: Sorry for so long in between posts, I've been very busy (the good kind!)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-4183447400014795010?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/qeIN2aCVneg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/qeIN2aCVneg/using-boost-bind-and-boost-function.html</link><author>noreply@blogger.com (Sohail Somani)</author><thr:total>5</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2008/11/using-boost-bind-and-boost-function.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-4867723890538613194</guid><pubDate>Sun, 05 Oct 2008 19:17:00 +0000</pubDate><atom:updated>2008-10-05T15:25:47.078-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">c++</category><category domain="http://www.blogger.com/atom/ns#">boost</category><title>Everything you ever wanted to know about tr1::function but were too afraid to actually know</title><description>Working title for a talk I'm giving October 16 at the &lt;a href="http://vancpp.org/"&gt;Vancouver C++ Users Group&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I find three patterns of usage around Boost Function/Bind:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;The right way&lt;/li&gt;&lt;br /&gt; &lt;li&gt;The wrong way&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Running away&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;My goal for this talk: attendees should no longer be in the dark about how Boost Function/Bind (and by extension, tr1 function/bind) work. If you are reading this blog, coming to this talk, not the author of this post and you have some things you'd like to hear covered, please feel free to leave some comments. I'm pretty sure the intersection of all those groups of people is the empty set but it never hurts to ask!&lt;br /&gt;&lt;br /&gt;Heckling must be reserved for the end.&lt;br /&gt;&lt;br /&gt;PS: Regular posting will resume some point soon!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-4867723890538613194?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/pRjtR92evjQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/pRjtR92evjQ/everything-you-ever-wanted-to-know.html</link><author>noreply@blogger.com (Sohail Somani)</author><thr:total>2</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2008/10/everything-you-ever-wanted-to-know.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-4344157724641342161</guid><pubDate>Thu, 31 Jul 2008 15:06:00 +0000</pubDate><atom:updated>2008-08-02T10:41:42.927-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">lisp</category><category domain="http://www.blogger.com/atom/ns#">qt</category><title>Qt/Lisp: more progress</title><description>I've replaced the unsightly &lt;tt&gt;(make-instance 'qstring :ch "Foo")&lt;/tt&gt; with a reader macro: &lt;tt&gt;#q"Foo"&lt;/tt&gt;. Ideally we'd use &lt;tt&gt;cl:string&lt;/tt&gt; and &lt;tt&gt;qstring&lt;/tt&gt; interchangeably but right now its too much of a PITA to make that work.&lt;br /&gt;&lt;br /&gt;I've also made it possible to use closures for slots (see example below.) Frickin sweet.&lt;br /&gt;&lt;br /&gt;Anyway, I started getting into the &lt;a href="http://doc.trolltech.com/4.3/mainwindows-dockwidgets.html"&gt;Dock Widgets example&lt;/a&gt; but lost interest after seeing all the code. &lt;a href="http://paste.lisp.org/display/64482"&gt;Here&lt;/a&gt; is the code so far. Not very concise yet but will get there. Once I get into make-it-less-ugly mode, I will probably copy what Paul did with &lt;a href="http://lisp-cffi-qt4.sourceforge.net/"&gt;EQL&lt;/a&gt; as he calls it now.&lt;br /&gt;&lt;br /&gt;&lt;s&gt;Also the :foreign-pointer thingy will go away when I get around to adding cffi type translations.&lt;/s&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-4344157724641342161?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/iDnybWa5pa0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/iDnybWa5pa0/qtlisp-more-progress.html</link><author>noreply@blogger.com (Sohail Somani)</author><thr:total>0</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2008/07/qtlisp-more-progress.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-3122616166564985534</guid><pubDate>Mon, 28 Jul 2008 23:04:00 +0000</pubDate><atom:updated>2008-07-28T19:09:23.252-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">python</category><category domain="http://www.blogger.com/atom/ns#">svn</category><title>svn-bisect</title><description>Well it was only a matter of time... &lt;a href="http://scons.tigris.org/source/browse/*checkout*/scons/branches/core/bin/svn-bisect.py?content-type=text%2Fplain&amp;rev=3249"&gt;svn-bisect.py&lt;/a&gt; lives!&lt;br /&gt;&lt;br /&gt;Greg Noel of SCons fame (is that really fame?) has committed a modification of a script I created whose purpose was to binary search the introduction of a bug in a SVN repository.&lt;br /&gt;&lt;br /&gt;Example usage of the script is &lt;a href="http://scons.tigris.org/issues/show_bug.cgi?id=2037"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Enjoy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-3122616166564985534?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/TMF2zao6cdc" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/TMF2zao6cdc/svn-bisect.html</link><author>noreply@blogger.com (Sohail Somani)</author><thr:total>0</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2008/07/svn-bisect.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-3990927677037015372</guid><pubDate>Mon, 28 Jul 2008 22:51:00 +0000</pubDate><atom:updated>2008-07-28T18:55:25.382-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">personal</category><category domain="http://www.blogger.com/atom/ns#">nothingtoseehere</category><title>Why complaining works..</title><description>My email to an online store:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Hey guys, I ordered product XYZ from your site yesterday. According to your shipping estimates, it should be here in 2-4 days. However, I see that it is not shipped yet. I have had one bad experience with your service before and would not like it to repeat. Please see that this is so.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Literally 5 minutes later:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Your order has been shipped.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Now if I can only get them to do it before I complain.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-3990927677037015372?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/XSPGINWW2As" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/XSPGINWW2As/why-complaining-works.html</link><author>noreply@blogger.com (Sohail Somani)</author><thr:total>2</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2008/07/why-complaining-works.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-1790320458741790045</guid><pubDate>Tue, 22 Jul 2008 17:04:00 +0000</pubDate><atom:updated>2008-07-27T19:59:05.580-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">lisp</category><category domain="http://www.blogger.com/atom/ns#">qt</category><title>Simple CFFI - Qt4 integration attempt</title><description>Update: Paul has sent me his code. He calls it "EQL" for ECL and Qt. Or something like that anyway! I have put it up &lt;a href="http://taggedtype.net/~sohail/lisp/eql-2008-07-24.tgz"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The author of the &lt;a href="http://lisp-cffi-qt4.sourceforge.net/"&gt;Simple CFFI - Qt4 integration attempt&lt;/a&gt; has contacted me to let me know that a modification of the above linked software is in commercial use. I have prodded him to release his modified version. He says he'll do it Real Soon Now (TM).&lt;br /&gt;&lt;br /&gt;I don't know if he is reading this blog but maybe a little pressure will help. Just kidding!&lt;br /&gt;&lt;br /&gt;What I like most about his method is the use of the introspection capabilities of Qt. Compared to the duct tape and glue I used, his is a lot more elegant. Currently, you cannot extend Qt in Lisp (via inheritance) but all the other goodies are still there. Indeed he tells me that for his application, he extended Qt from within C++ and used these extensions from his Lisp.&lt;br /&gt;&lt;br /&gt;I look forward to the update and to using the library.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-1790320458741790045?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/1pClBkaVOd4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/1pClBkaVOd4/simple-cffi-qt4-integration-attempt.html</link><author>noreply@blogger.com (Sohail Somani)</author><thr:total>2</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2008/07/simple-cffi-qt4-integration-attempt.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-3159387250960714266</guid><pubDate>Fri, 18 Jul 2008 17:22:00 +0000</pubDate><atom:updated>2008-12-08T21:20:03.909-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">lisp</category><category domain="http://www.blogger.com/atom/ns#">qt</category><title>Qt/Lisp: looking for feedback</title><description>Update: You can download the generated code from &lt;a href="http://taggedtype.net/~sohail/package.tgz"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The tubes were down this morning, so I managed to get up to tutorial 6 in my Qt/Lisp API. It covers about 95% of the API by design so most of the non-extension tutorials/examples should work.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://paste.lisp.org/display/63901"&gt;Tutorial 1:&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_NJChfbPZ2fA/SIDeB2YpWsI/AAAAAAAAAC4/JjX-aSairMI/s1600-h/tutorial1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_NJChfbPZ2fA/SIDeB2YpWsI/AAAAAAAAAC4/JjX-aSairMI/s200/tutorial1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5224419691109898946" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://paste.lisp.org/display/63902"&gt;Tutorial 2&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_NJChfbPZ2fA/SIDeT6lTQ5I/AAAAAAAAADA/n_bsHvr8TnQ/s1600-h/tutorial2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_NJChfbPZ2fA/SIDeT6lTQ5I/AAAAAAAAADA/n_bsHvr8TnQ/s200/tutorial2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5224420001474364306" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://paste.lisp.org/display/63903"&gt;Tutorial 3&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_NJChfbPZ2fA/SIDeUFoum0I/AAAAAAAAADI/k5WFqsLpLD8/s1600-h/tutorial3.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_NJChfbPZ2fA/SIDeUFoum0I/AAAAAAAAADI/k5WFqsLpLD8/s200/tutorial3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5224420004441529154" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://paste.lisp.org/display/63904"&gt;Tutorial 4&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_NJChfbPZ2fA/SIDeUCT_JTI/AAAAAAAAADQ/swwXN5ZydAM/s1600-h/tutorial4.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_NJChfbPZ2fA/SIDeUCT_JTI/AAAAAAAAADQ/swwXN5ZydAM/s200/tutorial4.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5224420003549226290" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://paste.lisp.org/display/63905"&gt;Tutorial 5&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_NJChfbPZ2fA/SIDeUUJJlDI/AAAAAAAAADY/A8bVadsAK6g/s1600-h/tutorial5.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_NJChfbPZ2fA/SIDeUUJJlDI/AAAAAAAAADY/A8bVadsAK6g/s200/tutorial5.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5224420008335610930" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;a href="http://paste.lisp.org/display/63906"&gt;Tutorial 6&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_NJChfbPZ2fA/SIDeUQ3qmwI/AAAAAAAAADg/EeaYKCV29kI/s1600-h/tutorial6.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_NJChfbPZ2fA/SIDeUQ3qmwI/AAAAAAAAADg/EeaYKCV29kI/s200/tutorial6.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5224420007456971522" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;I would like to hear your complaints, suggestions, feedback if you have any.&lt;br /&gt;&lt;br /&gt;Note that this API is a first draft and I thought it better to have something out there than wait until everything is perfect.&lt;br /&gt;&lt;br /&gt;To start with, my current complaints:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;(in-package :qt) -&gt; Nothing is actually exported from the package yet :-)&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;s&gt;(make-instance 'qstring ...) -&gt; A really verbose way to pass a string! Should convert lisp strings to qstrings automagically.&lt;/s&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Naming: instead of qpush-button, q:push-button&lt;/li&gt;&lt;br /&gt; &lt;li&gt;No way to extend Qt from within Lisp yet (&lt;a href="http://doc.trolltech.com/4.3/tutorial-t7.html"&gt;tutorial 7&lt;/a&gt; won't work)&lt;/li&gt;&lt;br /&gt; &lt;li&gt;&lt;s&gt;No way to attach arbitrary functions as slots&lt;/s&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Not Lispy enough.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;I expect to address most of these at some point though the "Not Lispy enough" complaint is a bit subjective.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-3159387250960714266?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/J79Yvp3knhI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/J79Yvp3knhI/qtlisp-looking-for-feedback.html</link><author>noreply@blogger.com (Sohail Somani)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_NJChfbPZ2fA/SIDeB2YpWsI/AAAAAAAAAC4/JjX-aSairMI/s72-c/tutorial1.png" height="72" width="72" /><thr:total>4</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2008/07/qtlisp-looking-for-feedback.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-6700781333683502992</guid><pubDate>Wed, 09 Jul 2008 16:56:00 +0000</pubDate><atom:updated>2008-07-09T13:46:50.526-04:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">personal</category><title>Sohail, it doesn't work anymore</title><description>Everyone has a story about when they were younger. For example, Joel Spolsky talks about his time in an army bakery (or something like that.) Sometimes, the stories are quite pathetic like Al Bundy and his high school football team. I am neither as exciting as Spolsky, nor as pathetic as Al Bundy (though I'm sure the latter is up for debate.)&lt;br /&gt;&lt;br /&gt;This story is about something that happened to me when I was younger that made me who I am today.&lt;br /&gt;&lt;br /&gt;I started programming quite late by geek standards. I was either 11 or 14 depending on whether you count batch files as programming. But I loved it. And when I got tired of programming, I'd program some more in FastTracker 2!&lt;br /&gt;&lt;br /&gt;For a while, I had a job as a pharmacist's assistant. This particular pharmacy had the option for delivery of prescriptions and other general items. The deliveries were done in the evening and were done by two very friendly guys named Krish and Sam.&lt;br /&gt;&lt;br /&gt;Part of my job here (besides preparing the methadone!) was to add up all the deliveries that these two guys did within some period of time and summarize for the boss. It used to take me hours in a busy month as it required use of some large Excel spreadsheet. So I resolved to solve that problem with my programming chops. I got the owner to agree to pay me hourly (wow, $10/hour!) and he told me not to spend "too much time" on it. So I guesstimated 40 hours until I would be able to deploy the application. He was fine with that.&lt;br /&gt;&lt;br /&gt;I was mostly right but near the end of it, while I was testing with the users (me), it turned out some other data collection was necessary. After discussing with the boss, he said it was important but not to spend "too much time" on it. By then, I had come to realize that "too much time" means "don't charge me more than I want to pay you." So I added it quickly, and it was done.&lt;br /&gt;&lt;br /&gt;I deployed the application in December of that year to rave reviews from the boss. I'm not sure if the other employees cared that much but I know that it made my life easier and the count of deliveries more accurate so I was happy.&lt;br /&gt;&lt;br /&gt;Due to other responsibilities (I think it was school?), I had to reduce my hours at the pharmacy. That was around June. I had trained the other people to use the application and it was becoming quite necessary for them to use if they wanted to retain their sanity.&lt;br /&gt;&lt;br /&gt;Fast-forward to November. I get a call. "Sohail, it's not working anymore." "Crap", I thought. What did I miss? I went into the pharmacy and fudged around in the flat files to see what could be wrong.&lt;br /&gt;&lt;br /&gt;It turns out that one of the data files was being named incorrectly. Can you guess which data file? Yes, it was the one I had added last just before I completed the project.&lt;br /&gt;&lt;br /&gt;I think I spent about 10 unpaid hours debugging the problem at home while studying for exams/finishing projects. It came down to this (in C++, I don't really recall the language):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// data1.cpp&lt;br /&gt;const char * months[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;// data2.cpp&lt;br /&gt;const char * months[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov ","Dec"};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Can you see the problem? In the second instance, I added a space after "Nov". So while data2.cpp was saving "Data2Nov Year.file", data1.cpp was saving "Data1NovYear.file" and the code that summarized the data was trying to open "Data&amp;lt;N&amp;gt;NovYear.file".&lt;br /&gt;&lt;br /&gt;Oops.&lt;br /&gt;&lt;br /&gt;I fixed this bug and apologized to the owner. I explained why it happened and that I fixed the code duplication. The boss said that he thought I should get an award for this software (a big ego boost!) and wondered if he could sell it to other people. Apparently he had been raving about it to his other pharmacist buddies. I don't remember what I said to him about that (something about me not having enough time to modify it to be generic enough as Sam and Krish were hardcoded!) but I really learned something that month.&lt;br /&gt;&lt;br /&gt;Fortunately, in this case, things turned out alright. So I swore to avoid similar problems in the future in case future clients were not as forgiving. How did I do this? Quite simply:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li&gt;Thorough testing&lt;/li&gt;&lt;br /&gt; &lt;li&gt;No copy-and-waste&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;My business cards have always had some variation of this. The current incarnation has something like "Do it once, do it right." Corny, but conveys my philosophy quite well. I will work very hard to reduce code duplication now. I try my best to write a test for each function/class that I write. Yes it is hard work. Yes it takes time. Quite frankly, software &lt;i&gt;is&lt;/i&gt; hard. But in the end, I get very few calls saying "Sohail, it doesn't work anymore."&lt;br /&gt;&lt;br /&gt;And no, you are not allowed to put a comment on this post saying "Sohail, it doesn't work anymore" :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-6700781333683502992?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/RZ796EotEPw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/RZ796EotEPw/sohail-it-doesnt-work-anymore.html</link><author>noreply@blogger.com (Sohail Somani)</author><thr:total>1</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2008/07/sohail-it-doesnt-work-anymore.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4168503339888369834.post-5496163434442401429</guid><pubDate>Tue, 24 Jun 2008 04:32:00 +0000</pubDate><atom:updated>2008-12-08T21:20:04.185-05:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">c++</category><category domain="http://www.blogger.com/atom/ns#">gtk</category><category domain="http://www.blogger.com/atom/ns#">gui</category><category domain="http://www.blogger.com/atom/ns#">gtkmm</category><title>Automatically rescale a Gtk::Image (and preserve aspect ratio)</title><description>Don't really have enough time to explain it all, but hopefully the comments help. Here are a couple of screenshots:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_NJChfbPZ2fA/SGB5Ta3T8WI/AAAAAAAAACk/qtPukoWkMpI/s1600-h/Screenshot-1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_NJChfbPZ2fA/SGB5Ta3T8WI/AAAAAAAAACk/qtPukoWkMpI/s200/Screenshot-1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5215301743030825314" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_NJChfbPZ2fA/SGB5bYP6vrI/AAAAAAAAACs/bCWC89awffY/s1600-h/Screenshot-2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_NJChfbPZ2fA/SGB5bYP6vrI/AAAAAAAAACs/bCWC89awffY/s200/Screenshot-2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5215301879767678642" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The image used in the examples above is &lt;a href="http://www.utahskies.org/image_library/deepsky/constellations/orionwa.jpg"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;And the code:&lt;br /&gt;&lt;br /&gt;&lt;pre class="cxx"&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;*&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;  Problem:&lt;br /&gt;&lt;br /&gt;  Using GTK, display an image in a window and rescale when the window&lt;br /&gt;  resizes preserving the aspect ratio.&lt;br /&gt;  &lt;br /&gt;  Analysis:&lt;br /&gt;&lt;br /&gt;  Gtk provides Gtk::Image which works on a Gdk::Pixbuf (pixel buffer)&lt;br /&gt;  which allows rescaling but without preserving aspect ratio.&lt;br /&gt;&lt;br /&gt;  Summary of solution:&lt;br /&gt;&lt;br /&gt;  Use a Gtk::Image embedded in a Gtk::AspectFrame and resize image&lt;br /&gt;  using dimensions determined by Gtk::AspectFrame. The AspectFrame&lt;br /&gt;  knows how to maintain a ratio so it does the messy work for us.&lt;br /&gt;&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="preprocessor"&gt;#&lt;/span&gt;&lt;span class="preprocessor"&gt;include&lt;/span&gt; &lt;span class="string"&gt;&amp;lt;&lt;/span&gt;&lt;span class="string"&gt;gtkmm.h&lt;/span&gt;&lt;span class="string"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="preprocessor"&gt;#&lt;/span&gt;&lt;span class="preprocessor"&gt;include&lt;/span&gt; &lt;span class="string"&gt;&amp;lt;&lt;/span&gt;&lt;span class="string"&gt;iostream&lt;/span&gt;&lt;span class="string"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;/// &lt;/span&gt;&lt;span class="comment"&gt;This Widget only scales the image but does not preserve&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/// &lt;/span&gt;&lt;span class="comment"&gt;aspect ratios.&lt;br /&gt;&lt;/span&gt;&lt;span class="keyword"&gt;s&lt;/span&gt;&lt;span class="keyword"&gt;truc&lt;/span&gt;&lt;span class="keyword"&gt;t&lt;/span&gt; &lt;span class="type"&gt;ScalingImage&lt;/span&gt; : &lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="constant"&gt;Gtk&lt;/span&gt;::&lt;span class="type"&gt;Image&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;  &lt;span class="keyword"&gt;explici&lt;/span&gt;&lt;span class="keyword"&gt;t&lt;/span&gt;&lt;br /&gt;  &lt;span class="function-name"&gt;ScalingImage&lt;/span&gt;(&lt;span class="constant"&gt;Glib&lt;/span&gt;::&lt;span class="type"&gt;RefPtr&lt;/span&gt;&amp;lt;&lt;span class="constant"&gt;Gdk&lt;/span&gt;::Pixbuf&amp;gt; &lt;span class="variable-name"&gt;pixbuf&lt;/span&gt;,&lt;br /&gt;               &lt;span class="constant"&gt;Gdk&lt;/span&gt;::&lt;span class="type"&gt;InterpType&lt;/span&gt; &lt;span class="variable-name"&gt;interp&lt;/span&gt; = &lt;span class="constant"&gt;Gdk&lt;/span&gt;::INTERP_BILINEAR):&lt;br /&gt;    &lt;span class="constant"&gt;Gtk&lt;/span&gt;::Image(pixbuf),&lt;br /&gt;    m_original(pixbuf),&lt;br /&gt;    m_interp(interp),&lt;br /&gt;    m_sized(&lt;span class="constant"&gt;false&lt;/span&gt;)&lt;br /&gt;  {&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;protected&lt;/span&gt;:&lt;br /&gt;  &lt;span class="keyword"&gt;virtual&lt;/span&gt;&lt;br /&gt;  &lt;span class="type"&gt;voi&lt;/span&gt;&lt;span class="type"&gt;d&lt;/span&gt;&lt;br /&gt;  &lt;span class="function-name"&gt;on_size_allocate&lt;/span&gt;(&lt;span class="constant"&gt;Gtk&lt;/span&gt;::&lt;span class="type"&gt;Allocation&lt;/span&gt; &amp;amp; &lt;span class="variable-name"&gt;r&lt;/span&gt;)&lt;br /&gt;  {&lt;br /&gt;    &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;This event is fired on all Widgets when their rectangle gets&lt;br /&gt;&lt;/span&gt;    &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;resized. So we rescale our image. But rescaling our image fires&lt;br /&gt;&lt;/span&gt;    &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;another resize event, and another, and another... You see the&lt;br /&gt;&lt;/span&gt;    &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;problem!&lt;br /&gt;&lt;/span&gt;    &lt;span class="comment-delimiter"&gt;//&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;&lt;/span&gt;    &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;The most straightforward solution is to not rescale the image&lt;br /&gt;&lt;/span&gt;    &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;the second time the event is fired. Hence the m_size toggle.&lt;br /&gt;&lt;/span&gt;    &lt;span class="comment-delimiter"&gt;//&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;&lt;/span&gt;    &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;Ideally I'd not like to do this but this was the best way I&lt;br /&gt;&lt;/span&gt;    &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;found!&lt;br /&gt;&lt;/span&gt;    &lt;span class="keyword"&gt;i&lt;/span&gt;&lt;span class="keyword"&gt;f&lt;/span&gt;(&lt;span class="negation-char"&gt;!&lt;/span&gt;m_sized)&lt;br /&gt;    {&lt;br /&gt;      &lt;span class="constant"&gt;Glib&lt;/span&gt;::&lt;span class="type"&gt;RefPtr&lt;/span&gt;&amp;lt;&lt;span class="constant"&gt;Gdk&lt;/span&gt;::Pixbuf&amp;gt; &lt;span class="variable-name"&gt;scaled&lt;/span&gt; = &lt;br /&gt;        m_original-&amp;gt;scale_simple(r.get_width(),&lt;br /&gt;                                 r.get_height(),&lt;br /&gt;                                 m_interp);&lt;br /&gt;      &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;Reset the image to be the new scaled image which&lt;br /&gt;&lt;/span&gt;      &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;will cause the second size-allocate signal&lt;br /&gt;&lt;/span&gt;      &lt;span class="constant"&gt;G&lt;/span&gt;&lt;span class="constant"&gt;tk&lt;/span&gt;::&lt;span class="constant"&gt;Image&lt;/span&gt;::set(scaled);&lt;br /&gt;&lt;br /&gt;      &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;Make sure we don't treat it as a rescale request &lt;br /&gt;&lt;/span&gt;      &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;next time&lt;br /&gt;&lt;/span&gt;      m_sized = &lt;span class="constant"&gt;true&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;    &lt;span class="keyword"&gt;else&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;      &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;Reaction to set above. Call the base class's on_size_allocate&lt;br /&gt;&lt;/span&gt;      &lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;function. Shouldn't I have to call this above too? Maybe it&lt;br /&gt;&lt;/span&gt;      &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;isn't necessary since it gets called anyway.&lt;br /&gt;&lt;/span&gt;      &lt;span class="constant"&gt;G&lt;/span&gt;&lt;span class="constant"&gt;tk&lt;/span&gt;::&lt;span class="constant"&gt;Image&lt;/span&gt;::on_size_allocate(r);&lt;br /&gt;&lt;br /&gt;      &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;Treat next resize event as a rescale&lt;br /&gt;&lt;/span&gt;      m_sized = &lt;span class="constant"&gt;false&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;&lt;span class="keyword"&gt;private&lt;/span&gt;:&lt;br /&gt;  &lt;span class="constant"&gt;Glib&lt;/span&gt;::&lt;span class="type"&gt;RefPtr&lt;/span&gt;&amp;lt;&lt;span class="constant"&gt;Gdk&lt;/span&gt;::Pixbuf&amp;gt; &lt;span class="variable-name"&gt;m_original&lt;/span&gt;;&lt;br /&gt;  &lt;span class="constant"&gt;Gdk&lt;/span&gt;::&lt;span class="type"&gt;InterpTyp&lt;/span&gt;&lt;span class="type"&gt;e&lt;/span&gt; &lt;span class="variable-name"&gt;m_interp&lt;/span&gt;;&lt;br /&gt;  &lt;span class="type"&gt;boo&lt;/span&gt;&lt;span class="type"&gt;l&lt;/span&gt; &lt;span class="variable-name"&gt;m_sized&lt;/span&gt;;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;// &lt;/span&gt;&lt;span class="comment"&gt;This widget automatically scales the image but preserves the&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/// &lt;/span&gt;&lt;span class="comment"&gt;aspect ratio of the original image. This is accomplished via use&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/// &lt;/span&gt;&lt;span class="comment"&gt;of the AspectFrame class&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;///&lt;/span&gt;&lt;span class="comment"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/// &lt;/span&gt;&lt;span class="comment"&gt;Ideally would like this to be a Gtk::Image subclass.&lt;br /&gt;&lt;/span&gt;&lt;span class="keyword"&gt;s&lt;/span&gt;&lt;span class="keyword"&gt;truc&lt;/span&gt;&lt;span class="keyword"&gt;t&lt;/span&gt; &lt;span class="type"&gt;AspectPreservingScalingImage&lt;/span&gt; : &lt;span class="keyword"&gt;public&lt;/span&gt; &lt;span class="constant"&gt;Gtk&lt;/span&gt;::&lt;span class="type"&gt;AspectFrame&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;  &lt;span class="keyword"&gt;explici&lt;/span&gt;&lt;span class="keyword"&gt;t&lt;/span&gt;&lt;br /&gt;  &lt;span class="function-name"&gt;AspectPreservingScalingImage&lt;/span&gt;(&lt;span class="constant"&gt;Glib&lt;/span&gt;::&lt;span class="type"&gt;RefPtr&lt;/span&gt;&amp;lt;&lt;span class="constant"&gt;Gdk&lt;/span&gt;::Pixbuf&amp;gt; &lt;span class="keyword"&gt;const&lt;/span&gt; &amp;amp; &lt;span class="variable-name"&gt;pixbuf&lt;/span&gt;,&lt;br /&gt;                               &lt;span class="constant"&gt;Gdk&lt;/span&gt;::&lt;span class="type"&gt;InterpType&lt;/span&gt; &lt;span class="variable-name"&gt;interp&lt;/span&gt; = &lt;span class="constant"&gt;Gdk&lt;/span&gt;::INTERP_BILINEAR):&lt;br /&gt;    m_img(pixbuf,interp)&lt;br /&gt;  {&lt;br /&gt;    &lt;span class="variable-name"&gt;set&lt;/span&gt;(&lt;span class="constant"&gt;Gtk&lt;/span&gt;::ALIGN_CENTER, &lt;span class="constant"&gt;Gtk&lt;/span&gt;::ALIGN_CENTER,&lt;br /&gt;        &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;Aspect ratio of frame&lt;br /&gt;&lt;/span&gt;        pixbuf-&amp;gt;get_width()/&lt;span class="type"&gt;float&lt;/span&gt;(pixbuf-&amp;gt;get_height()));&lt;br /&gt;    &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;This makes it appear as if there is no frame&lt;br /&gt;&lt;/span&gt;    set_shadow_type(&lt;span class="constant"&gt;Gtk&lt;/span&gt;::SHADOW_NONE);&lt;br /&gt;    &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;This allows a minimum size&lt;br /&gt;&lt;/span&gt;    set_size_request(pixbuf-&amp;gt;get_width()/2,pixbuf-&amp;gt;get_height()/2);&lt;br /&gt;    &lt;span class="comment-delimiter"&gt;/&lt;/span&gt;&lt;span class="comment-delimiter"&gt;/ &lt;/span&gt;&lt;span class="comment"&gt;Finally, add the image to be managed&lt;br /&gt;&lt;/span&gt;    add(m_img);&lt;br /&gt;  }&lt;br /&gt;&lt;span class="keyword"&gt;private&lt;/span&gt;:&lt;br /&gt;  &lt;span class="type"&gt;ScalingImag&lt;/span&gt;&lt;span class="type"&gt;e&lt;/span&gt; &lt;span class="variable-name"&gt;m_img&lt;/span&gt;;  &lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span class="type"&gt;i&lt;/span&gt;&lt;span class="type"&gt;n&lt;/span&gt;&lt;span class="type"&gt;t&lt;/span&gt; &lt;span class="function-name"&gt;main&lt;/span&gt;(&lt;span class="type"&gt;int&lt;/span&gt; &lt;span class="variable-name"&gt;argc&lt;/span&gt;, &lt;span class="type"&gt;char&lt;/span&gt;* &lt;span class="variable-name"&gt;argv&lt;/span&gt;[])&lt;br /&gt;{&lt;br /&gt;  &lt;span class="keyword"&gt;if&lt;/span&gt;(argc != 2)&lt;br /&gt;  {&lt;br /&gt;    &lt;span class="constant"&gt;std&lt;/span&gt;::cout &amp;lt;&amp;lt; &lt;span class="string"&gt;&amp;quot;Usage: &amp;quot;&lt;/span&gt; &amp;lt;&amp;lt; argv[0] &amp;lt;&amp;lt; &lt;span class="string"&gt;&amp;quot; &amp;lt;image-file&amp;gt;&amp;quot;&lt;/span&gt; &amp;lt;&amp;lt; &lt;span class="constant"&gt;std&lt;/span&gt;::endl;&lt;br /&gt;    &lt;span class="keyword"&gt;return&lt;/span&gt; 1;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;span class="constant"&gt;Gtk&lt;/span&gt;::&lt;span class="type"&gt;Mai&lt;/span&gt;&lt;span class="type"&gt;n&lt;/span&gt; &lt;span class="variable-name"&gt;kit&lt;/span&gt;(argc,argv);&lt;br /&gt;&lt;br /&gt;  &lt;span class="constant"&gt;Gtk&lt;/span&gt;::&lt;span class="type"&gt;Windo&lt;/span&gt;&lt;span class="type"&gt;w&lt;/span&gt; &lt;span class="variable-name"&gt;win&lt;/span&gt;;&lt;br /&gt;  &lt;span class="constant"&gt;Gtk&lt;/span&gt;::&lt;span class="type"&gt;VBo&lt;/span&gt;&lt;span class="type"&gt;x&lt;/span&gt; &lt;span class="variable-name"&gt;box&lt;/span&gt;;&lt;br /&gt;  win.add(box);&lt;br /&gt;&lt;br /&gt;  &lt;span class="constant"&gt;Gtk&lt;/span&gt;::&lt;span class="type"&gt;LinkButto&lt;/span&gt;&lt;span class="type"&gt;n&lt;/span&gt; &lt;span class="variable-name"&gt;lb&lt;/span&gt;(&lt;span class="string"&gt;&amp;quot;http://www.utahskies.org/image_library/deepsky/constellations/orionwa.jp&lt;/span&gt;&lt;span class="string"&gt;g&lt;/span&gt;&lt;span class="string"&gt;&amp;quot;&lt;/span&gt;);&lt;br /&gt;  &lt;span class="type"&gt;AspectPreservingScalingImag&lt;/span&gt;&lt;span class="type"&gt;e&lt;/span&gt; &lt;span class="variable-name"&gt;apsi&lt;/span&gt;(&lt;span class="constant"&gt;Gdk&lt;/span&gt;::&lt;span class="constant"&gt;Pixbuf&lt;/span&gt;::&lt;span class="type"&gt;create_from_file&lt;/span&gt;(&lt;span class="variable-name"&gt;argv&lt;/span&gt;[1]));&lt;br /&gt;&lt;br /&gt;  box.pack_start(lb,&lt;span class="constant"&gt;Gtk&lt;/span&gt;::PACK_SHRINK);&lt;br /&gt;  box.pack_start(apsi);&lt;br /&gt;  &lt;br /&gt;  &lt;span class="keyword"&gt;struc&lt;/span&gt;&lt;span class="keyword"&gt;t&lt;/span&gt; &lt;span class="type"&gt;launch_browser&lt;/span&gt;&lt;br /&gt;  {&lt;br /&gt;    &lt;span class="keyword"&gt;static&lt;/span&gt;&lt;br /&gt;    &lt;span class="type"&gt;voi&lt;/span&gt;&lt;span class="type"&gt;d&lt;/span&gt;&lt;br /&gt;    &lt;span class="function-name"&gt;doit&lt;/span&gt;(&lt;span class="constant"&gt;Glib&lt;/span&gt;::ustring &lt;span class="keyword"&gt;const&lt;/span&gt; &amp;amp; &lt;span class="variable-name"&gt;addr&lt;/span&gt;)&lt;br /&gt;    {&lt;br /&gt;      &lt;span class="constant"&gt;std&lt;/span&gt;::&lt;span class="type"&gt;strin&lt;/span&gt;&lt;span class="type"&gt;g&lt;/span&gt; &lt;span class="variable-name"&gt;command&lt;/span&gt;(&lt;span class="string"&gt;&amp;quot;firefox &amp;quot;&lt;/span&gt;);&lt;br /&gt;      command += addr.c_str();&lt;br /&gt;      &lt;span class="constant"&gt;std&lt;/span&gt;::system(command.c_str());&lt;br /&gt;    }&lt;br /&gt;  };&lt;br /&gt;&lt;br /&gt;  lb.signal_clicked().connect&lt;br /&gt;    ( &lt;br /&gt;     &lt;span class="constant"&gt;sigc&lt;/span&gt;::bind(&lt;br /&gt;                &lt;span class="constant"&gt;sigc&lt;/span&gt;::ptr_fun(&lt;span class="constant"&gt;launch_browser&lt;/span&gt;::doit),&lt;br /&gt;                lb.get_uri()&lt;br /&gt;                )&lt;br /&gt;      );&lt;br /&gt;      &lt;br /&gt;&lt;br /&gt;  win.show_all();&lt;br /&gt;&lt;br /&gt;  &lt;span class="constant"&gt;Gtk&lt;/span&gt;::&lt;span class="constant"&gt;Main&lt;/span&gt;::run(win);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4168503339888369834-5496163434442401429?l=uint32t.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/uint32t/~4/GbNjbhXhETQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/uint32t/~3/GbNjbhXhETQ/automatically-rescale-gtkimage-and.html</link><author>noreply@blogger.com (Sohail Somani)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_NJChfbPZ2fA/SGB5Ta3T8WI/AAAAAAAAACk/qtPukoWkMpI/s72-c/Screenshot-1.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://uint32t.blogspot.com/2008/06/automatically-rescale-gtkimage-and.html</feedburner:origLink></item></channel></rss>

