Tuesday, 7 April 2015

My C++ wishlist

I regularly use C++ for my own personal projects, that's normally because my personal projects are gamedev related and the power and performance of C++ comes into its own here. My day job however is writing Python, and although C++11 has completely revolutionised the language, there are occasionally some things I miss when I'm coding at home.

Here's a quick list of things I would love to be added to C++, but I'm pretty sure won't be!

1.  Symbolic imports


Imports in Python are amazingly clean and flexible. The ability to just type:

from os.path import join

...knowing full well that it's not going to dump the entire contents of another header file into my code is wonderful. C++ sucks here, including headers slows down compilation, it means you must use header guard #defines, and forces you to do strange tricks (like pre-declaring classes) to make things work. It's painful. I hear that modules are coming in some future C++ version, but IMO they can't come soon enough!

2. Decorators


In Python, you can write a function that wraps another function, allowing you to perform pre/post operations and have them called automatically whenever that function is called. The original function seems unchanged. In Python this implementation of the decorator pattern looks like this:

@some_property_function
def the_function_that_is_wrapped():
    pass

Since C++11 introduced lambdas defining such wrapper properties could be very similar to Python. For example:

std::function<void ()> some_property_function(std::function<void ()> the_func) {
    return []() {
        //Do pre-stuff
        return the_func();
    }
}

All that's missing is some way to apply such a decorator to a function or method. Although I'm sure that's not as trivial as it sounds.

3. Context Managers


In C++, there is no try/finally. If you want to ensure that something is destroyed no matter what the solution comes in the form of RAII.

However, RAII means that you end up having code like this:

if(something) {
   something();
   { //<< Seamingly pointless scope block that needs a comment
       Lock some_lock_which_will_be_freed;
       do_locked_thing();
   }
}

Brilliant. It would be amazing to have an actual syntax for this behaviour, a 'with' statement is perfect!

with Lock()as some_lock_which_will_be_freed {
    do_locked_thing();
}

Now there are no weird extra braces without explanation!

4. Overloading of the '.' operator


This would be tricky to implement, but I've lost track of the number of times I've had to rely on overloading '->' just because overloading '.' isn't possible.

5. Read-only properties


Properties in Python allow you to add apparently public attributes to a class, which actually implicitly return the result of a function. These kind of read-only properties make using your API nicer, and allow you to abstract away the implementation of how that property's value is calculated. For example:

auto class_size = my_school.pupil_count / my_school.room_count;

If you actually exposed pupil_count and room_count as public variables, and then decide actually, you can calculate pupil_count on the fly by summing the school_year.pupil_counts you are forced to make all calling code do this instead:

auto class_size = my_school.pupil_count() / my_school.room_count;

A minor change perhaps, but if your API is used by hundreds of third parties, you're a little bit in trouble. Of course, you could have just used a method in the first place - but it makes the calling code more cumbersome, and less readable.

It would just be nicer and more flexible if C++ allowed you to do this:

property int pupil_count() { return pupil_count_; }

6. Tuple/Pair support in the range-for loop


C++11 brought us range-based for loops which allow you to iterate any container with begin()/end() methods.

for(auto& something: my_vector) {}

Unfortunately, in the case of dictionary style classes like map and unordered_map, 'something' ends up as a std::pair. Meaning you have to do this:

for(auto & something: my_map) {
    auto key = something.first;
    auto value = something.second;
}

That quickly gets tiresome, it would be nice if you could do something like this:

for(auto key, auto value: my_map) {
      // yay!
}

Friday, 27 February 2015

Snippet: Class Properties in C++11

Update: I discovered several bugs with the initial implementation, so I've updated this post with a more complete solution.

Properties as seen in Python and C# are a pretty nice language feature, they allow you to have the syntax of accessing a public member variable, yet have that access still go through a getter or setter function.

I have to say I'm not totally sold on RW properties (I feel that if you are intending to change the state of a class, you should be forced to make it clear by calling a setter function) but I like RO properties, they remove the need to call a function to just access a value, and still allow you to check pre/post conditions or log access.

C++ doesn't have properties, if you Google around there's a general consensus that they don't fit the language well. However, I got a bit tired of my game engine's API having an excessive number of function calls. Here's an example:

TextureID rtt = window().new_texture(false);
window().mesh(rect_mesh)->set_texture_on_material(0, rtt);

It would be far nicer to be able to write:

TextureID rtt = window->new_texture(false);
window->mesh(rect_mesh)->set_texture_on_material(0, rtt);

... and still have the control that a getter function provides. So I wrote a Property template class, it looks like this..

template<typename Container, typename T>
class Property {
public:
    Property(Container* _this, T Container::* member):
        this_(_this),
        getter_([member](Container* self) -> T& {
            return self->*member;
        }) {
    }

    Property(Container* _this, T* Container::* member):
        this_(_this),
        getter_([member](Container* self) -> T& {
            return *(self->*member);
        }) {
    }

    Property(Container* _this, std::shared_ptr<T> Container::* member):
        this_(_this),
        getter_([member](Container* self) -> T& {
            return *(self->*member);
        }) {
    }

    Property(Container* _this, std::function<T& (Container*)> getter):
        this_(_this),
        getter_(getter) {

    }

    /*
     *  We can't allow copy construction, because 'this_' will never be initialized
     */
    Property(const Property& rhs) = delete;

    Property operator=(const Property& rhs) {
        assert(this_); //Make sure that this_ was initialized

        getter_ = rhs.getter_;
        // Intentionally don't transfer 'this_'
    }

    inline operator T&() const { return getter_(this_); }
    inline T* operator->() const { return &getter_(this_); }
private:
    Container* this_ = nullptr;
    std::function<T& (Container*)> getter_;
};



Container is the class you are adding the property to, T is the type of the property.

Thanks to C++11 allowing initialization of members in the body of the class, and the awesome syntax of lambdas, we can use the Property template like so:

Property<WindowBase, Watcher> watcher = {
    this, [](const WindowBase* self) -> Watcher& {
        if(!self->watcher_) {
            throw LogicError("Watcher has not been initialized");
        } else {
            return *self->watcher_.get();
        }
    }
};

Or, if you just want to wrap a member variable:

Property<WindowBase, Console> console = { this, &WindowBase::console_ };

Unfortunately we can't override the '.' operator in C++ so we can't get the exact same syntax as C# or Python, but the -> operator is good enough (and as a lot of my engine's accessors return pointers, it actually made things more consistent).

Wednesday, 29 October 2014

A Fuzzy Sublime-like String Matching Algorithm

Those of you who pay attention to what I'm up to, will know that one of my long running projects is to write my own code editor.

One of the features that's been implemented for a while was a basic filename search via a popup search box. This approach is seen in other editors like Sublime Text, and it's an efficient way to quickly navigate between files.

I wasn't happy with my search matching though, it used a hacky Levenshtein distance algorithm for ordering. It was slow, and to keep it usable I had to disregard many matches that the user might have been looking for.

After much thought I've come up with a much better algorithm for fuzzy matches, I'm going to call it the Kazade Ranking Algorithm, because I can.

Tuesday, 21 October 2014

On Google App Engine, Ancestor Queries are Almost Never What You Need


Recently, the company where I work announced the alpha release of Djangae, a compatibility layer that allows your Django application to work on App Engine, and to store your data in the App Engine Datastore. One of the things missing from the alpha was support for the Datastore's so called "Ancestor queries".

The App Engine Datastore is a remarkable feat of engineering. It's a non-relational database, which can scale to store mind-boggling amounts of data and deal with crazy high amounts of traffic. Of course, the sacrifice is that it's non-relational - so there are no joins, aggregate queries or the like. And if you want to count things then expect it to take some time!

Monday, 26 May 2014

A Public Domain C++11 1D/2D/3D Perlin Noise Generator

Recently I needed to generate some simple procedural textures for a game I'm working on - after a quick search I found that the top result was licensed under the GPL which is no good to me. After a while I did find an MIT licensed one, but as all these code snippets are just C++ ports of Ken Perlin's improved noise function written in Java, I figured I might as well write my own from scratch and license it under the public domain. So, here it is, in all its glory:

Tuesday, 20 May 2014

Writing a C++ Completion Provider for GtkSourceView

Over the last few weeks I've been implementing Python code completion in my homebrew text editor. After a lot of work I have most of the backend code worked out, the file parsing and indexing generally works.

The next step was to create a CompletionProvider to tell the Gtk+ text view about any suggestions that my code completion engine had. In my mind, I just had to do the following:
  1. Subclass CompletionProvider, implement the populate() function
  2. Call view().get_completion()->add_provider(my_provider);
  3. Wallow in the joy of having working code completion
However, it's not as simple as that, because the C++ GtkSourceView bindings suck, although they'd suck even less if they had some sensible documentation, or examples...

Wednesday, 23 April 2014

Bug Trackers Suck!

Recently, I've been thinking a lot about bug trackers. For those who aren't in the know, bug trackers are websites that allow software developers to, well, track bugs in their software.

More specifically they allow management of the entire life cycle of a bug report. Starting with the report itself which probably comes from a user of the software, all the way through to the final deployment of the fixed code in the application.

There are numerous free and paid for bug trackers out there - all of them suck.

Well, I guess that's a bit unfair, let me rephrase that, all of them suck if you aren't a developer.