Quercus Robusta
Overview
Quercus Robusta is (a name of) reusable opensource C++ library I am developing.
Among its main features are:
It should work on majority of UN*X
flavors and compilers. Some features
(e.g., stack back-trace) are only available under GNU environment.
Extensive use of
garbage collector based on reference counting.
Library is built
around separate implementation and interface
hierarchies (both are implemented through C++ inheritance). Root
of interface hierarchy is
Top abstract class and root of
implementation hierarchy is Object
(As posteriori note it was clearly unwise to call it Object
because this identifier is somewhat reserved by other libraries
(CORBA being first to come to my mind). Hopefully it will be possible
to resolve this through namespaces, which doesn't work in the
current state of GNUart.).
Separation of sub-classing and sub-typing dictates use of virtual inheritance
virtually everywhere.
Utility classes and interfaces:
Enumeration,
Iterator,
Iterable,
AbstractFactory,
Map etc.
Implementation of
various container-like data structures:
List, Array,
Stack, Set etc.
Containers are arranged into implementation and interface hierarchies.
Base type of all containers classes is Container.
Containers are
thought of as collections of slots. To each slot a value can be assigned
(subject to container-specific constraints). An address of slot within the container
is called Position (due to historical reasons).
In other words, Position is a way to describe
slot within the container. For example in Array
there are: first slot, last slot, n-th slot etc. Appropriately, there are
Positions, denoting first, last and n-th slot in
the Array. Depending on the configuration of
the Array some or all of them may point to the
same slot or be invalid (e.g., if n is beyond the range of valid indices).
Positions
are primary interface to
Containers. Container
interface contains methods to enumerate all positions in the container,
that can be used to scan container for value, pretty-print it etc.
Position is somewhat similar to
STL
Iterators, but there are important differences:
Position is first class abstract class
so to speak, not a ``Concept'' as STL Iterator.
Fast
String class with UNICODE support.
Strings are stored in two-byte UCS2 encoding and can be converted to and fro
UTF8 and some 8-bit encodings.
All
erroneous conditions are reported through exception mechanism.
Debugging
features: optional pre-conditions and post-condition testing,
C++ exceptions are thrown if run-time assertions fail. Debugger
of choice can be attached to process on the fly or stack back-trace can be
produced.
Distributed
under GNU License. Drop
me a message if you
managed to compile it :).
For further information see
here.
Sources
Last tarball available at
quercus-0.0.3.tgz
(224k --- it is smaller than before because doc/html
is no longer here). It doesn't use autoconf or alike, sorry.
Then look into doc/tuning-macros.txt for the list of
preprocessor symbols affecting build process. Edit Makefile and do
make makedirs clean depend build
This will leave test executable in top-level directory.
Previous version:
quercus-0.0.2.tgz (283k).
Changes in version 0.0.3
Platform-independent graphics
capabilities added. Member classes of class (namespace surrogate)
Aq define interfaces to graphic primitives like windows
and graphic contexts. There are three implementations currently:
Xq on top of X Window System,
Wq on top of Win32 interface and
Cq on top of beloved (n)curses!
Multi-threading added: new interfaces
ThreadFactory, ThreadSystem,
Thread, Mutex,
CondVar, Semaphore. Threads
can be created with either pthread (starting from given C function) or JDK
style (executing method Runnable::run()).
MGuard allows automatic mutex locking/unlocking on block
entering/leaving.
Basic classes were updated to synchronize properly.
Win32 platform is
now almost fully supported (with multithreading).
New preprocessor
macros added. Now it is possible to turn individual
setting on/off without touching code. (Briefly, for each "boolean" parameter X
described in doc/tuning-macros.txt there are two macros:
WANT_X and UNWANT_X to switch X on and off respectively. This allows to compile the
same sources on the different platforms.
Tree
container interface (and default implementation) added (it is rather ugly though).
The name of the game
Quercus is Latin for oak (Quercus is official genus name).
Robusta (to which word robust obviously stems) means having strength and vigor,
tough, dependable
and ... oaken i.e. made of oak. None the less robusta is standard epithet of quercus
in Latin poetry. Another point is that quercus is of feminine gender, contrary
to explicit masculine ending!
Rationale
First I shall try to enumerate, what this library was and is not:
fast. Whenever there was
a possibility to choose particular design or implementation, it was chosen
to reuse existing parts of library, to be extensible and clean rather than efficient.
Yet overall performance is satisfactory (there are some especially brain
damaged and slow implementations, e.g., DumbDictionary as
its name supposes, but they will be replaced by more elaborated as time will pass by).
Moreover, considerable amount of time in default configuration is spend in pre-post-conditions
checking and other debugging activities (allocation tracing etc.). You can switch them
off by playing with defines in inc/defines.h. Also GC
can be made optional in future versions.
Familiar. This library doesn't
mimic any particular framework, although some parts of it may reminiscent you of
Smalltalk containers, MVC and JDK (not STL The Horrible). The definitive source
of inspiration is Patterns Book.
Simple. It is not that simple
just to use QR and there is a number of reasons to that. First, C++ is not simple language.
Second, C++ has no garbage collection and if you need it, you have to implement it manually,
everywhere. Third, this library still has no client interface proper. What it has
is some reusability framework. There should be more concrete classes directly usable
by user, with simplified interfaces etc.
Main point of QR is re-usability. There is the single method
ContainerAdapter::print that pretty-print any container
whatsoever, methods ContainerAdapter::find,
ContainerAdapter::equals and so on are defined in base class,
so implementor only needs to define one method
ContainerAdapter::getEnumeration to get fully
functionable container. Of course, default implementations can be inefficient and
can be overridden if needed.
Positions made it possible to write generic algorithms
to search, copy and perform set-theoretic-like operations (union, intersection,
Cartesian product, power set etc.) on containers.
There should be something important I forgot to mention.
|