Range Based for-loops in C++11
Posted by cheshirekow in C++ Discoveries and Notes, Programming on August 2, 2013
One of the new features of C++11 that is a complete win in my opinion is the support for range-based for-loop syntax. Judicious use allows for significantly more compact and readable code. However, one thing that is lacking from this feature is the ability to iterate over a range of integers. This isn’t a problem, however, because it is very easy to implement.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | // This file compiles as a single unit, you can test it by saving it // as range_for.cpp and compiling with // g++ -std=c++11 -o range_for range_for.cpp // Adjust the interface as you see fit // Implementation (put this in a header) // ------------------------------------------------------------------ /// encapsulates a range of integral numbers for use in a c++11 range-based for /// loop template< typename T> struct Range { /// the begin() and end() functions must return an iterator with a specific /// interface struct Iterator { T val; ///< storage for the actual value /// implicit construction from the value type Iterator( T val ):val(val){} /// the range-based for loops attempt to dereference an iterator using /// this operator T operator*(){ return val; } /// the range-based for loops quit when the comparison of iter != end /// returns false bool operator !=( T other ){ return val != other; } /// iterators in a range-based for loop must have the prefix increment /// operator Iterator& operator++(){ ++val; return *this; } /// we likely want to implicitly convert to the value type operator T(){ return val; } }; private: T m_begin; ///< the first integral value T m_end; ///< one past the last integral value public: /// construct a range [begin, end) Range( T begin, T end ): m_begin(begin), m_end(end) {} /// interface required by range-based for loop Iterator begin(){ return m_begin; } /// interface required by range-based for loop Iterator end() { return m_end; } }; /// return an object which can be used in a range-based for loop template <typename T> Range<T> range( T begin, T end ) { return Range<T>(begin,end); } // Usage // ------------------------------------------------------------------- #include <iostream> int main(int argc, char** argv) { std::cout << "Static ranges\n----------------\n"; std::cout << "\nint:\n"; for( int i : range(1,5) ) std::cout << " i: " << i << "\n"; std::cout << "\nunsigned int:\n"; for( unsigned int i : range(1u,5u) ) std::cout << " i: " << i << "\n"; std::cout << "\nlong:\n"; for( long i : range(1L,5L) ) std::cout << " i: " << i << "\n"; std::cout << "\nDynamic range (program args)\n----------------\n"; for( int i : range(0,argc) ) std::cout << i << " : " << argv[i] << "\n"; return 0; } |
The range<T>( T begin, T end )
function template returns a Range<T>
object which supports the required interface for range-based loops. It has a begin
and end
method, both of which return an iterator. The iterator has the same storage says as the integral type used to instantiate the templates. It is implicitly convertable to and from the integral type. Futhermore, it has the prefix ++
operator, and can be “dereferenced” to get the stored integral value.
The implementation is likely to yield compiled code equivalent to a normal for loop.
The output of the demo program above is:
josh@Nadie:~/Desktop$ g++ -std=c++11 -o range_for range_for.cpp josh@Nadie:~/Desktop$ ./range_for arg1 arg2 arg3 arg4 arg5 Static ranges ---------------- int: i: 1 i: 2 i: 3 i: 4 unsigned int: i: 1 i: 2 i: 3 i: 4 long: i: 1 i: 2 i: 3 i: 4 Dynamic range (program args) ---------------- 0 : ./range_for 1 : arg1 2 : arg2 3 : arg3 4 : arg4 5 : arg5 josh@Nadie:~/Desktop$
Making a list of everything you’ve installed with apt-get
Posted by cheshirekow in Ubuntu on July 28, 2013
As a clean install of ubuntu is often the only reliable way to upgrade, it’s useful to know everything that you’ve installed manually. You could get a list of everything that’s marked in for installation with something like:
dpkg --get-selections | grep -v deinstall > my-selections
but that list tends to be very long and it includes all the dependencies. So if you install a meta package which depends on a specific version of some other package you’ll be trying to install that specific version after upgrade, which is not what we want. In that case all we want is the meta package.
Luckly, apt-get keeps a history of every time it is called. These history files are in /var/log/apt/history.log.(\d).gz
. Each entry in that list contains a “Commandline: …” line which lists the command line that was executed. Thus we can get a list of everything we’ve installed by grepping through these files.
The first script is a perl script which parses “Commandline: …” entries:
1 2 3 4 5 6 7 8 9 10 11 12 | #!/usr/bin/perl # parse_apt_log.pl while(<>) { if(/^Commandline: apt-get install(.+)/) { unless(/--reinstall/) { print join("\n", split(/\s+/, $1) ); } } } |
and the second is a bash script which pipes the contents of those history files to the perl script
1 2 3 4 5 6 7 8 | #!/bin/bash outfile="$(mktemp)" gunzip -c /var/log/apt/history.log.*.gz | ./parse_apt_log.pl > $outfile sort "$outfile" rm "$outfile" |
Which gives an output like:
josh@Nadie:~/Desktop$ ./make_pkg_list.sh astyle bitcoin-qt debathena-pharos-support dhex digikam docbook2x docbook5-xml docbook-xsl-ns firefox flip fontforge fop gdm git-svn gnucash gyp icedtea6-plugin icedtea-7-plugin jhead latexml libapache2-mod-fastcgi libavcodec-extra-53 libav-dbg libavdevice-extra-53 libavfilter-extra-2 libavformat-extra-53 libavutil-extra-51 libcairo2-dbg libcrypto++-dev libcurl4-gnutls-dev libfcgi-dev libgdal1-dev libglade2.0-cil libgnome-desktop-dev libgtkglext1-dev libjpeg-turbo-progs libjson0-dev libmosquitto0 libpcre3-dev libqtsysteminfo1 libtelepathy-qt4-2 libtidy-dev libusb-0.1-4 libusb-1.0-0-dev libusb-dev libxml2-dev libxml2-utils linux-generic markdown meld mtpfs mtp-tools network-manager-openvpn okular openjdk-7-jre owncloud-client pcsxr pcsxr pdfedit python-rosinstall qt-sdk qtsixa ragel ros-fuerte-desktop-full ros-fuerte-pr2-* ros-fuerte-pr2-simulator ros-fuerte-rqt rtmpdump sixad smplayer sound-juicer spawn-fcgi sqlitebrowser synapse ufraw ufraw-batch uncrustify universalindentgui untex vlc-dbg xdotool xmlstarlet xmlto xsltproc
You can reinstall this list on the new system with sudo apt-get install `tr '\n' ' ' < package-list.txt`
, where tr will remove the newlines.
Other install notes for upgrading to ubuntu 13.04:
To install deb packages from the command line along with their dependencies install gdebi-core
from the repositories. Then run, for instance sudo gdebi google-chrome-stable-current_amd64.deb
.
To remove overlay scrollbars:
gsettings set com.canonical.desktop.interface scrollbar-mode normal
To allow rawdisk vmdk's in Virtualbox the user must be a member of the disk
group:
sudo usermod -a -G disk user
C++ FreeFontStack
Posted by cheshirekow in C++ Discoveries and Notes, openfontstack on February 6, 2013
I’ve been doing a lot of research into free software font technologies and as a consequence I’ve been playing around a lot with Freetype2 and Fontconfig (actually the library interface libfontconfig). These are “straight up” c-libraries and so I (personally) find the interface a bit “clunky” in C++ code. Don’t get me wrong, I wouldn’t presume to criticize their design as it is clear the authors/maintainers are far more knowledgeable about this stuff than I am… but from a users perspective I desire a bit more.
So… I’ve written some C++ wrappers for freetype2 and fontconfig. The main goals in these projects are:
- Don’t change the usage patterns of the library
- Provide a pointer-like type which automatically performs reference counting for reference counted objects
- Provide a pointer-like type which exposes member-functions where relevant
- Provide a pointer-like type which still allows access to the public data members of the underlying structures
- Allow access to the native c-pointer for use in parts of the library that I haven’t finished wrapping
So far… cppfontconfig wraps more or less all the functionality of libfontconfig. I’d still like to add some interface for assignment by touples in order to grab error codes when desired without the error being part of the function signature. Perhaps in the future.
cppfreetype isn’t nearly as complete (freetype2 is a much larger library). I still haven’t decided the appropriate way to deal with structures which are normally stack allocated. I do however have wrappers for FT_Face, FT_GlyphSlot, and an iterface for iterating over contours and points in an FT_Outline.
These libraries are released as GPLv3. I have public git repositories and publicly accessible doxygen documentation available in the links below. No bug tracker though since I’m giving up on redmine.
library | source repository | documentation |
---|---|---|
cppfreetype | git://git.cheshirekow.com/cppfreetype.git | www.cheshirekow.com/~projects/cppfreetype |
cppfontconfig | git://git.cheshirekow.com/cppfontconfig.git | www.cheshirekow.com/~projects/cppfontconfig |