I write a lot of C++ code for Windows. There are a lot of Windows APIs which expose cool functionality and are implemented using COM; for me this currently means Direct2D, DirectWrite, Direct3D, DXGI, and Windows Imaging Component. In terms of presenting a compatible ABI, COM is a good thing (and is certainly nicer than straight flattening a C++ API to a C API). That said, COM looks extremely clunky in modern C++, for the following reasons:
HRESULT return value rather than by throwing an exception. In almost all cases, the correct thing to do upon seeing a non-successful HRESULT is to throw an exception, and so the default behaviour should be to throw an exception (rather than the current default of disregarding the return value).HRESULTs, actual return values end up becoming out-parameters. This precludes the use of method chaining, the use of auto in C++11, and other nice things.std::pair or a std::tuple would be preferable to the current situation of having multiple out-parameters.AddRef and Release called at all appropriate points in the program, which is an additional burden on the programmer. With C++11's move semantics, there is almost no reason for manual reference counting.void or typed) along with a count (of either bytes or elements). In a lot of usage, a complete container gets passed, which should be accepted as-is. For example, given std::wstring str, it should be allowable to say obj->DrawText(str) rather than obj->DrawText(str.c_str(), str.size()), and likewise obj->DrawText(L"Message") rather than obj->DrawTect(L"Message", sizeof(L"Message") / sizeof(wchar_t) - 1).REFIID. I should be able to write rt->CreateSharedBitmap(surface) rather than having to write rt->CreateSharedBitmap(__uuidof(surface), surface).const* rather than const&. My personal opinion is that in modern C++, if a pointer shouldn't ever be null (i.e. is non-optional) and doesn't change what it points to (which for all intents and purposes, is true for method parameters), then it should always be a reference rather than a pointer.const&) rather than accepting a const* and having a default value of null.ID2D1Foo rather than D2::Foo.CamelCase, which looks slightly out of place alongside my default of camelCase.Some of those reasons are fairly minor, others are a major nuisance, but in aggregate, their overall effect makes COM programming rather unpleasant. Some people take small measures to attack one of the reasons individually, such as CHECK_HRESULT macro for throwing an exception upon an unsuccessful HRESULT (but you still need to wrap each call in this macro), or a com_ptr<T> templated smart pointer which at least does AddRef and Release automatically (but you then need to unwrap the smart pointer when passing it as a parameter to a COM method). I think that a much better approach is to attack all of the problems simultaneously. It isn't as easy as writing a single macro or a single smart pointer template, but the outcome is nice-to-use COM rather than COM-with-one-less-problem.
As with switching on Lua strings, my answer is code generation. I have a tool which:
d3d10.h, d3d10_1.h, d2d1.h, dwrite.h, dxgi.h, and wincodec.h).AddRef and Release are handled automatically by copy construction, move construction, copy assignment, and move assignment.HRESULT, then the wrapper checks for failure and throws an exception accordingly.std::tuple if there was more than one out-parameter, or an out-parameter on a method which already had a non-void and non-HRESULT return type).As an example, consider the following code which uses raw Direct2D to create a linear gradient brush:
In one of the projects I'm currently working on, Lua is used a lot as a data description language. As a result, there are many occasions where I'd like to run a switch statement work over a Lua string. One example of this is the following function:
"Line\0Stuff" will result in a LineArt rather than an UnknownArt, but usually this is acceptable. A further refinement might also make use of the string length:memcmp rather than strcmp. However, compared to the very first (non-functional) code fragment, this is harder to read and harder to maintain. This point is important to bear in mind, but things will get worse still before they get better. It just so happens that in the project I'm working on, the Lua library is statically linked. This means I can take advantage of Lua's implementation details safe in the knowledge that the implementation isn't going to change. The detail which I'd like to take advantage of is that Lua calculates a hash value for each string, and stores this in a header prior to the string contents. It also stores the length in this header, which we can also take advantage of. This train of thought leads to the following code fragment:strcmp, this version isn't perfect. It is highly likely (at least for strings longer than 4 characters) that there will be some other strings of the same length and hash value, but this is acceptable to me. On the positive side, this version should be extremely quick, as switching over a hash should be faster than sequential memcmps. Unfortunately, not only is this version unreadable and unmaintainable, it is also unwritable.
At this point, enter code generation. It is an entirely mechanical process to translate the original (non-functional) code into hash-based dispatch code, and furthermore the hash calculations are best done by a machine. Therefore I've written a preprocessing script for C++ source files which performs this translation. The input looks almost like the original (non-functional) code, with the addition of some markers:
#ifdef LUA_STRING_SWITCH, throws away any existing #else block, and then writes an #else block based on the contents of the switch, resulting in something like:LUA_STRING_SWITCH isn't defined, and so the hash-based dispatch gets used. At edit time, I use the folding features of an IDE to hide the nasty hash-based dispatch, so all I see is:Introduction to simple iterators in Lua
Let us begin by considering what a simple iterator is. In Lua, a simple iterator is a function. Each time you call the function, you get back the next value in the sequence. In the following example, f is (assumed to be) a simple iterator:
string.gmatch returns a simple iterator, but it is questionable whether or not this is mandated by the language. In particular, LuaJIT returns a full iterator rather than a simple iterator; see later]
As Lua functions can return multiple values, it seems logical to allow iterators to produce multiple values per call, and this is indeed allowed. In the following example, f is (assumed to be) a simple iterator which produces two values per call:
To signal that it has finished producing values, an iterator returns nil. Well, nearly; an iterator can signal completion by returning no values, by returning a single nil, or by returning multiple values with the first value being nil. With this in mind, the previous example can be rewritten to use a loop rather than an explicit number of calls to f:
for loop can be used to achieve the same effect:string.gmatch is termed a simple iterator factory, as it returns a simple iterator (f). Equipped with this knowledge of how simple iterators work, we can write a simple iterator factory which emulates the numeric for loop:Introduction to full iterators in Lua
Looking at range in slightly more detail, we see that every time it is called, it returns a function, and that the function has three upvalues (init, limit, and step). From an esoteric efficiency point of view, it would be nice to have less upvalues (or ideally no upvalues at all). Full iterators are one way of achieving this. Whereas a simple iterator is just a function (f), a full iterator is a three-tuple (f,s,v). As with a simple iterator, f is still a function (or something with a __call metamethod). As for the two new bits, s is an opaque value which is passed as the first parameter to each call of f, and v is an opaque value which is passed as the second parameter to the first call of f. Subsequent calls of f pass the first return value from the previous call of f as the the second parameter.
Written out formally like that, full iterators sound a little bit odd, but once you've wrapped your head around it, they are really quite reasonable. As an example, let us rewrite range to be a full iterator factory rather than a simple iterator factory. For this, we'll take s to be limit, and v to be init - step, like so:
for loop is designed to work with full iterators, this version of range can be used just like the previous version:Looking at this version of range, the returned function only has one upvalue (step). In real terms, this means that 32 less bytes of space are allocated on the heap as compared to the three upvalue version. Admittedly this isn't much, and it hardly justifies the language support for full iterators. Rather more convincing are the pairs and ipairs full iterator factories from the Lua standard library. The full iterator machinery is precisely what these two functions need in order for their iterator functions to have no upvalues at all, meaning that you can iterate through a table without having to allocate anything on the heap, as in the following example:
map function:map function for Lua iterators might be:ConcatMapping Lua iterators
Jumping back to Haskell again, consider the slightly more complex concatMap function:
map function in Lua:map still permits the previous example:coroutine.yield for each additional tuple:Suppose we want to create a C++ std::string object, and we know how long the resulting string will be, and we know how we'll generate the content of the string, but we do not have a copy of said content in memory. As a concrete example, consider taking a block of memory, and returning a string whose content is the hexadecimal representation of that memory block. The result should satisfy the following tests:
std::stringstream tool is used, which may be slow due to be extremely flexible, and also due to not knowing how long its result will be. Given that we do not need most of the flexibility of std::stringstream, and we know how long the result will be (2 for hexifyChar, and 2 * len for hexify), we should expect to be able to do better.
As we want to construct a std::string, let us look at its constructors, and see which ones might work for us:
string ();string (const string& str);string (const string& str, size_t pos, size_t n = npos);string (const char * s, size_t n);string (const char * s);string (size_t n, char c);template<class Iterator> string (Iterator begin, Iterator end);None of these look particularly like what we want, but the last option might be viable if we can wrap a hexifying algorithm inside an iterator. If said iterator is infact a random access iterator, then the constructor will be able to obtain the length of the result before it starts fetching the individual characters.
Writing an STL-compatible iterator usually takes a lot of code, but we can use boost::iterator_facade to do most of the work for us, giving us the following code:
Just over a year ago, I looked at Lua 5.2 (work 3). Lua evolves slowly, and 5.2 still isn't quite finished, though perhaps it will be by the time the Lua Workshop 2011 rolls round in September (at which I hope to give a talk). In the mean time, Lua 5.2 (beta rc2) has been released, and this time I've identified the changes since 5.1 by annotating the new reference manual with them: An Annotated Lua 5.2 (beta rc2) Reference Manual.
Presenting the changes inline with the reference manual, as compared to just listing them, provides more context for the changes, as well as making things easier to consume by reducing the density of new information. If you have any good ideas for other ways of presenting this change information, then get in touch.
Recent comments
16 weeks 6 days ago
17 weeks 17 hours ago
17 weeks 3 days ago
33 weeks 17 hours ago
38 weeks 3 days ago
38 weeks 5 days ago
38 weeks 5 days ago
40 weeks 6 days ago
44 weeks 1 hour ago
46 weeks 5 days ago