Stefan's Assorted C++ Snippets
===============================

  This directory contains a collection of various C++ snippets I use
  over and over again.

  This package is public domain; I believe it's only standard techniques
  collected in one place.

  Note that all functions that work with strings actually use string_t,
  which is defined in string.h, depending on STREU_CONFIG_USE_BASICSTRING.


Configuration / Installation
-----------------------------

  Configuration is entirely manual. An automatic installer will follow.
  Maybe.

  + copy "cpluslib/config.in" to "cpluslib/config.h" and edit it to suit
    your needs. If you leave out this step, it'll use the defaults from
    the .in file.

  + possibly edit "cpluslib/types.h".

  + run "make" (Unix) or "make -fmakefile.bor" (Borland C++/Win32)

  + you'll get a file "cpluslib.a" or "cpluslib.lib" which you'll link
    when you use the library.


cpluslib/array.h
-----------------

  Classes to treat arrays as first-class objects. Instead of passing
  around the initial element pointer and the size separately, these
  classes combine this information into one object. In addition, there
  are functions to virtually transpose arrays, taking subranges, etc.


cpluslib/assert.h
------------------

  Those come both in "release" and "debug" flavour, select the latter
  by #defining STREU_CONFIG_DEBUG.

  + ASSERT(expr): standard assert macro. This one raises SIGSEGV when
    an assertion fails; I find it easier to debug this way.
  + FAIL(): shorthand of saying ASSERT(0).
  + FIXME(text): like ASSERT(0), but this one allows specifying a text
    to show instead, and prevents the program to compile in release mode
    (rationale: don't release anything with known bugs in it...).
  + CTASSERT(expr): compile-time assert. Can stand anywhere a function
    declaration can be (`CTASSERT(sizeof(x) == 9)').
  + checked_cast<T>(expr): in release: static_cast. In debug mode,
    the type is checked (dynamic_cast). Only works for non-virtual
    inheritance in polymorphic classes.


cpluslib/bitops.h
------------------

  + rol8(value, count): left-rotate 8-bit quantity.
  + rol{16,32}, ror{8,16,32}: likewise.
  + isPowerOfTwo(x): true iff x is a power of 2.


cpluslib/buffer.h
------------------

  + Buffer<T>: growable buffer of elements of type T. Less general than
    std::string/std::vector, but intended to be faster, and have a
    guaranteed representation. When std::vector becomes 100% guaranteed
    array-based, this one might be obsolete.
  + Array<T>: auto_ptr-like thing for arrays; unsharable, uncopyable etc.
    Intended to be used like a C99 VLA.


cpluslib/cstring.h
-------------------

  + This contains the C++ string operation (find_first_of etc.) operating
    on raw char arrays. These are also used as the basis of simple_string
    and substring.
  + These names are members of a class `cstring_util', not a namespace.

  For consistency with the standard library, we use
  lower_case_with_underbars instead of mixedCaseLikeEverywhereElse.


cpluslib/enum.h
----------------

  + Enumeration<T>: a Java-like enumeration class. Use where STL iterators
    don't do (e.g. where having to support the possibility of keeping
    multiple iterators to different places doesn't work out simply, for
    example a wrapper around `readdir', or where polymorphy is needed).


cpluslib/format.h
------------------

  Type-safe "sprintf" workalike.

  Usage: `string_t s = format("fmtstring") << arg << arg2'. `fmtstring'
  must be a C string. See comment in format.cc for instructions.

cpluslib/fixed_vector.h
cpluslib/fixed_list.h
----------------------

  Fixed-size containers. See fixed_containers.txt.


cpluslib/holder.h
------------------

  This exports a class "ObjectHolder" which provides lifetime control for
  a number of Objects placed in it: when the ObjectHolder dies, it
  destroys all the Objects it contains.


cpluslib/let.h
---------------

  + restorer<T>: use to guarantee restoring a variable's value even in case
    of an exception. E.g. by writing `restorer<int> saver(intvar);', you
    guarantee that intvar has its current value when leaving this block,
    regardless what happens. restorer has a weird copying semantic, so
    don't do that.
  + let(var,value): quasi-dynamic scope:
        let(intvar, value),
            doSomething();
    sets intvar to value while doing doSomething(), then restores its
    value.


cpluslib/maybe.h
-----------------

  + Maybe<T,V>: simple wrapper around a T, with the additional
    semantic information that value V means 'unknown'.


cpluslib/misc.h
----------------

  + countof(x), where x is an array: returns the dimension of x.
  + Object: object with virtual destructor. Often useful. If
    STREU_CONFIG_TOSTRING is also defined, this object also has
    a toString() method which is also pretty useful even if you do not
    override it (if you have gcc, that is).
  + zeroFill(x): wrapper for memset, zeroes out an object (note that only
    char members are guaranteed to be zero afterwards!)


cpluslib/sigslot.h
-------------------

  Qt-like signals, but in 100% C++.

  + Signal0 is a signal taking no parameters, Signal1<T> and Signal2<T,T2>
    take one and 2 parameters.
  + sig.add(object, &TObject::method), sig.add(static_function) add
    listeners. All signals accept functions which match exactly, or
    which don't take parameters. 'add' returns a SignalHandler*,
    simply 'delete' it to release the connection (see below).
  + sig.raise(args) raises the signal

  SignalConnection provides lifetime management, so you don't actually
  have to mess with 'delete'. If you create a SignalConnection, it can
  take control over exactly one connection. The connection is
  automatically cleared when the SignalConnection or the Signal dies
  (you can detect the latter case by SignalConnection::isConnected
  turning false).


cpluslib/smallset.h
--------------------

  A class encapsulating a set with up to 32 (resp. number of bits in an
  unsigned long). Especially useful for sets of enums, as in
     enum Elem { One, Two, Three };
     SmallSet<Elem> set;
     set += One;
     if (set.contains(Three)) { ... }
  This class is essentially optimized away by gcc, which is a Good
  Thing(tm).

  Supports all the usual set primitives:
  + 'set | set', 'set | elem' (resp. '+' instead of '|') for set union
  + 'set & set' for intersection
  + 'set - set', 'set - elem' for set difference
  + 'set ^ set', 'set ^ elem' for symmetric difference
  + compound-assignment versions thereof
  + 'set == set', 'set != set'
  as well as some members:
  + set.contains(set), set.contains(elem) to test whether this set
    contains another one, or contains an element
  + set.containsAnyOf(set) if the two sets have any common element
  + set.empty(), set.nonempty() to test for emptiness

  The static member SmallSet<Elem>::allUpTo(N) generates a set
  containing all elements whose ordinal value is N or lower.


cpluslib/smartptr.h
--------------------

  Smart pointer with reference counting. All obvious operations supported,
  including passing a smart pointer through a dumb one.

  + Ptr<T> points at a single T (or derived-from-T, if it has a virtual
    dtor).
  + ArrayPtr<T> points to an array of T.

  This assumes (void*)derived_ptr == (void*)(base*)derived_ptr, which
  isn't guaranteed by ISO C++, but usually holds as long as you only use
  single inheritance. In addition, you can't reliably initialize a Ptr<>
  to anything else than 0 before main starts.

  Passing a smart pointer through a dumb one happens to be an operation
  I frequently need (the dumb pointer usually is "this"). Unfortunately,
  this makes dumb assignments slow, because all reference counts need to
  be registered in a global std::map). In addition, we can't guarantee
  formally that an object doing `Ptr<T> p = this' is actually allocated
  on the heap.


cpluslib/sstring.h
-------------------

  An efficient string class, where efficiency means code size. Almost
  compatible to std::string. It is expected to be not much slower than
  std::string.

  + simple_string: the string class

  Efficiency is gained by not using temporaries with destructors; this
  unfortunately prevents us from being 100% ISO compatible. See comment
  in sstring.cc for more information. Additionally, this does not throw
  on length overflow (actually, length overflow is not handled at all).

  Proof of concept: with #define STREU_CONFIG_USE_BASICSTRING:
      text    data     bss     dec     hex filename
     59580    8368       0   67948   1096c pcc-v2/vcrplay.o
    404005   86956    6632  497593   797b9 pcc-v2/playvcr

  With #undef STREU_CONFIG_USE_BASICSTRING (i.e. using simple_string):
      text    data     bss     dec     hex filename
     28787    5520       0   34307    8603 pcc-v2/vcrplay.o
    343877   80128    6856  430861   6930d pcc-v2/playvcr
  (gcc-2.95.2 on Linux/x86).


cpluslib/string.h
------------------

  Some string primitives:
  + strCaseCmp: case-insensitive string comparison
  + strTrim/strLTrim/strRTrim: trim whitespace
  + strLCase/strUCase/strUCFirst: case conversion
  + itoa: integer -> string
  + strIndent: indents a string possibly containing \n by prepending
    a prefix to each line
  + strFirst/strRemove/strSplit: string splitting
  + string_split_iterator: ForwardIterator for treating a string split
    at a certain sequence (e.g. ":" for passwd files) as an STL sequence.

  In addition:
  + string_t: typedef to either simple_string or std::string (the latter
    if STREU_CONFIG_USE_STD_STRING is defined)
  + functions to convert between simple_string, string_t and std::string:
    toStringType, toSimpleString, toStandardString


cpluslib/substr.h
------------------

  This contains a class that wraps a char array plus a length into an
  almost std::string-compatible interface, without any worries about
  allocation. This is mainly intended for temporary views onto a constant
  string_t, for example, in parsers. `substring' has:
  + find, rfind, find_first_of, ...
  + compare
  + substr
  + data
  + empty, length
  + clear, assign
  Note that *you* must make sure that the memory assigned to a substring
  instance remains valid. It is almost invariably an error to have a
  class member of type substring.


cpluslib/types.h
-----------------

  Exact-width integer types. Intended as a central place to change
  them when needed.

  + uint{8,16,32}: unsigned integers
  + int{8,16,32}: signed

cpluslib/util.h
----------------

  This one includes all of the above. You should probably not use it.
