Porting from the 1.2 to 2.0 series of c++-gtk-utils

The 1.2 and 2.0 series of c++-gtk-utils

The 2.0 series of c++-gtk-utils is only compilable in C++0x/11. Because of this, the 1.2 series is not at an end nor deprecated: it will be some time before it can be assumed that all programs will be written to use only C++0x/11, or that all generally installed compilers will support C++0x/11. Therefore, if new features are added to c++-gtk-utils, it is intended that they will be added to both branches at the same time.

However, some features have more flexible usage in the 2.0 series than in the 1.2 series, because of the availability of variadic templates, rvalue references and perfect forwarding, together with new ways of creating callable objects (via std::bind or lambda expressions).

The differences between the series are explained in more detail below. The 2.0 series of the library defines the symbol CGU_API_VERSION with the value 20 in the header file c++-gtk-utils/cgu_config.h, which can be used for conditional compilation purposes where it is intended that user code should be compilable against both series.

Compatibility

The c++-gtk-utils-1.2 series is compilable in both C++98/03 and C++0x/11. The c++-gtk-utils-2.0 series however is only compilable in C++0x/11: it uses amongst other things variadic templates to extend the usefulness of callback objects, and some other features only available in C++0x/11, such as rvalue references, and replaces std::auto_ptr smart pointers by std::unique_ptr.

c++-gtk-utils-2.0 is mainly API compatible with c++-gtk-utils-1.2. The main aspects of user code which may need to be changed to use the 2.0 series relate to:

1. The replacement of std::auto_ptr by std::unique_ptr in Cgu::Thread::Thread, Cgu::Thread::JoinableHandle and Cgu::TextPrintManager. However, to maintain source code compatibility, the library can be compiled with the --with-auto-ptr configuration option, which will cause std::auto_ptr to continue to be used instead of std::unique_ptr in relevant public interfaces. If the library is compiled with that configuration option, in the 2.0 series the header file c++-gtk-utils/cgu_config.h will also define the symbol CGU_USE_AUTO_PTR which can be used for conditional compilation purposes.
2. The use of variadic templates. This has the following effects on source code compatibility:
     (a) Callback::Callback is now typedef'ed to Callback::CallbackArg<> instead of Callback::CallbackArg<void>, and similarly the typedefs of Callback::Functor, Callback::SafeFunctor and Emitter. However, assuming that users have always used Callback, Emitter, etc instead of CallbackArg<void>, EmitterArg<void> and so forth, then this change will not be noticed.
     (b) A TypeTuple struct is no longer used to provide more than one unbound argument. This means that, say, Cgu::CallbackArg<TypeTuple<int, int, int> > in the 1.2 series just becomes Cgu::CallbackArg<int, int, int> in the 2.0 series.
     (c) The Cgu::DoIf::mem_fun() and Cgu::DoIf::fun() conditional compilation functions can now represent functions taking any number of arguments. This means that where the referenced functions are overloaded, explicit disambiguation is required in all cases (it is no longer possible to avoid disambiguation where the number of arguments are different).
3. operator==(), operator!=() and operator<(), and std::hash specializations, have been provided for comparisons of GobjHandle, GvarHandle, IntrusivePtr, SharedHandle, SharedLockHandle, SharedPtr and SharedLockPtr objects, to enable them to be more easily looked up in containers and to enable them to be used as keys in associative containers. This will cause a double definition error if user code provides its own comparison operators or std::hash specializations for them. To omit these functions and specializations to avoid double definition, the library can be compiled with the --without-smart-ptr-comp (or --with-smart-ptr-comp=no) configuration option. Thus, the presence of these functions and specializations is the default but there is an option for their omission, whereas the 1.2 series works the other way around, as although these functions (but not std::hash specializations) are available in the 1.2 series from version 1.2.12 onwards, they are not the default.

Enhancements

The main enhancements with the 2.0 series are that:

1. CallbackArg and FunctorArg objects constructed with the usual Callback::make() or Callback::make_ref() syntax can now take five bound arguments instead or a maximum of two, and may now take an unlimited number of unbound arguments (as may the associated EmitterArg and SafeEmitterArg objects). Alternatively, they may also be constructed from any callable object having a void return type, which (if using std::bind) has no limits to bound arguments or the ordering of bound with unbound arguments.
2. The Cgu::DoIf::mem_fun() and Cgu::DoIf::fun() conditional compilation functions can now represent functions taking any number of arguments.
3. Thread::Future objects can represent functions taking up to three arguments where the function is a non-static member function, and four arguments in respect of any other function, instead of the previous maximum of two. In addition, Future objects can be constructed from any callable object (which can take any number of arguments using std::bind).
4. gstream and fdstream objects are now available for the char32_t (u32gistream, etc) and char16_t (u16gistream, etc) types, and character set conversion functions are provided between utf32 and utf8, and utf16 and utf8, for char32_t and char16_t.

Configuration

It should be noted that the pkg-config files offered by c++-gtk-utils have changed their format. Version 1.2 provided c++-gtk-utils-1.2.pc when compiled against GTK+2, and c++-gtk-utils-1.3.pc when compiled against GTK+3, which looking back on it was somewhat odd numbering. The 2.0 series offers c++-gtk-utils-2-2.0.pc when compiled against GTK+2, and c++-gtk-utils-3-2.0.pc when compiled against GTK+3.

The 2.0 series is parallel-installable with the 1.2 series. User code can be set up to use different library versions using the pkg-config files mentioned above. The versions compiled against GTK+2 are also parallel-installable with the versions compiled against GTK+3, so at any one time a user may have four versions installed and individually usable, namely 1.2 for GTK+2, 1.2 for GTK+3, 2.0 for GTK+2 and 2.0 for GTK+3.