BOOST Libraries
// Use the boost auto link feature which automatically chooses // the correct library version #define BOOST_LIB_NAME boost_unit_test_framework #include <boost/config/auto_link.hpp>
Anwendungsbeispiel boost::condition
//shared data definitions (e.g. class attributes) boost::mutex m_mutex; boost::condition m_condition; // within Thread A boost::mutex::scoped_lock lock(m_mutex); // start some action to be executed within another thread B // now wait until the other thread is ready, // i.e. the condition becomes true m_condition.wait(lock); // the lock will be released before blocking // when wait returns the mutex has been locked again // within Thread B // Before starting the action wait until Thread A has entered wait() boost::mutex::scoped_lock lock(m_mutex); // execute some action // inform thread A that we are ready here m_condition.notify_one(); // unlock mutex (e.g. automatically at end of function scope)
Definition SyncUtils::WaitableCondition
// Possible implementation for class WaitableCondition
class WaitableCondition : private boost::noncopyable
{
public:
    // Constructor
    WaitableCondition (bool in_autoReset = true)
        :
        m_autoReset  (in_autoReset),
        m_condIsTrue (false)
    {}
    // Set and reset the condition
    void Set (bool in_state)
    { 
        boost::mutex::scoped_lock lock(m_mutex);
        m_condIsTrue = in_state;
        if (m_condIsTrue ) m_condition.notify_one();
    }
    // Check condition without waiting
    bool IsTrue (void)
    {
        boost::mutex::scoped_lock lock(m_mutex);
        return m_condIsTrue;
    }
    // Wait until condition becomes true
    // If the condition has already been set the function
    // will immediately return without calling boost-wait().
    void WaitUntilTrue (void)
    {
        boost::mutex::scoped_lock lock(m_mutex); 
        if (!m_condIsTrue)
        {
             // we really have to wait until someone calls
             // Set(true)
             m_condition.wait(lock);
        }
        if (m_autoReset) m_condIsTrue = false;
    }
    // Wait until condition becomes true (return true)
    // or the given timeout has elapsed (return false)
    bool TimedWaitUntilTrue (long in_timeoutMs)
    {
        boost::mutex::scoped_lock lock(m_mutex);
        if (!m_condIsTrue)
        {
            boost::xtime timeInterval = 
                ConvertFromMilliSec(in_timeoutMs);
            if (!m_condition.timed_wait(lock, timeInterval)
                return false;
        }
        if (m_autoReset) m_condIsTrue = false;
        return true;
    }
private:
    bool             m_autoReset;
    bool             m_condIsTrue;
    boost::mutex     m_mutex;
    boost::condition m_condition;
}
Anwendungsbeispiel SyncUtils::WaitableCondition
//shared data definitions (e.g. class attributes) SyncUtils::WaitableCondition m_condition; // within Thread A // start some action to be executed within another thread B // or assume that someone else has done this or will do this // simply wait until the condition has become true m_condition.WaitUntilTrue(); // within Thread B // execute some action // now set the condition m_condition.Set(true);
{
    boost::scoped_ptr<std::string> sp(new std::string(“Hallo”));
    // Check for existence and print the value
    if (sp)
        std::cout << *sp << ‘\n’;
    // Get the size of the string
    size_t i = sp->size();
    // Change the value of the string
    *sp = “New text”;
} // sp destrucor deletes the string
Wichtig: die verwalteten Objekte müssen durchgängig als shared_ptr weitergegeben werden. Würde ein Objekt zwischendurch als raw pointer behandelt und an anderer Stelle wieder in einen (dann unabhängigen) neuen shared_ptr zur Verwaltung gegeben, so würde dieser SmartPtr von einem falschen Referenzcount ausgehen und unabhängig von den anderwo zu diesem Objekt existierenden SmartPointern das Objekt abbauen.
besondere Funktionalitäten:
Vorteil: this kann wie ein SmartPtr behandelt werden.
Der ReferenzCount kann z.B. über folgende Basisklasse zur Verfügung gestellt werden:
class RefCount
{
    int m_refCount;
public:
    RefCount() : m_refCount(0){}
    virtual ~RefCount(){}
    // directly implement the needed free functions here in the scope
    // of this base class (multithreading not yet considered!)
    friend void intrusive_ptr_add_ref(RefCount* in_p)
    {++in_p_>m_refCount;}
    friend void intrusive_ptr_release(RefCount* in_p)
    {if (--in_p_>m_refCount==0) delete in_p;}
}
numeric_cast (Überwachung des Wertebereiches)
long val = 7; char c = boost::numeric_cast<char>(val); // ok val = 257; c = boost::numeric_cast<char>(val); // exception bad_numeric_cast is thrown here unsigned int ui; int i = -12; ui = boost::numeric_cast<int>(ui); // exception bad_numeric_cast is thrown here
lexical_cast
// string to int
std::string s=”43”;
int i = boost::lexical_cast<int>(s);
// float to string
float f= 3.14;
s=boost::lexical_cast<std::string>(f);
// failed conversion
s=”Text without numbers”;
i=boostlexial_cast<int>(s);
// -> exception bad_lexical_cast
// A simple converter function to string which allows
// more readable calls
template <typename T>
std::string ToString (const T& arg)
{
    try {return boost::lexical_cast<std::string>(arg);}
    catch(boost::bad_lexical_cast& e)
    {return “”;}
}
// Usage
std::string s=ToString(412);
BOOST_STATIC_ASSERT
// Restricted to compile time expressions, i.e., values and operators
// must be known to the compiler
// ensure that a template is instantiated only with integer types
template <typename T>
class MyClass
{
    BOOST_STATIC_ASSERT(boost::is_integral<T>::value);
};
// ensure that a template function is used only for a special
// range of constant values
template <int i>
MyFunction()
{
    BOOST_STATIC_ASSERT(i>=1 && i<=10);
}
boost::noncopyable
// The following class should not allow copies of itself
class MyClass : boost::noncopyable // private inheritance
{
    // declaring copy contructor and assignment operator as private
    // is no longer necessary
};
Konzept less_than_comparable
// concept requirs the implementation of bool operator<(const T&, const T&)
class MyClass : boost::less_than_comparable<MyClass> // Barton-Nackman
{
    std:string m_name;
public:
    friend bool operator<(const MyClass& lhs, const MyClass& rhs)
    {return lhs.m_name < rhs.m_name;}
};
Operatoren für verschiedene Typen
// The following string class should also work with the char* type
class MyString : boost::addable<MyString,
    bost::addable2<MyString, const char*> > 
{
public:
    explicit MyString (const char*);
    MyString(const MyString&);
    // Operators to implement
    MyString operator=(const MyString&);
    MyString& operator+=(const MyString&);
    MyString& operator+=(const char*);
};
// The base classes add implementation for following operators:
// MyString operator+(const MyString&, const MyString&);
// MyString operator+(const MyString&, const char*);
// MyString operator+(const char*, const MyString&);
Syntax für regular expressions
. = beliebiges Zeichen
* = 0 oder beliebig viele Wiederholungen
+ = beliebig viele Wiederholungen, aber mindestens einmal
? = keine oder genau eine Wiederholung
? = Ziel shortest possible match, als Zuatz zu * oder +
\d = Ziffer
\w = Wort (besser als [a-zA-Z], da Internationalisierung berücksichtigt
\1 = Referenz auf erste gefundene SubExpression
{n} = n Wiederholungen
{2,4} = 2 bis 3 Wiederholungen
{2,} = mindestens 2 Wiederholungen
[abc] = Alternativen entweder a oder b oder c
[a-c] = Alternativen, abgekürzt als Bereich
[^abc] = ungleich a,b,c
| = Trenner für Alternativen
\A = Beginn des Zeichenpuffers
\Z = Ende des Zeichenpuffers
Beispiele:
// 3 Ziffern, ein Wort aus Buchstaben, ein beliebiges Zeichen, 2 Ziffern
// oder „N/A“, ein Leerzeichen dann das erste Wort nochmals
boost::regex reg ("\\d{3}(a-zA-Z+).(\\d{2}|N/A)\s\1)");
Searching
// Calculate the number of occurences for new and delete
boost::regex reg („(new)|(delete)“);
boost::smatch m;
std::string s =”Any text containing new and delete..”;
int newCounter    = 0;
int deleteCounter = 0;
std::string::const_iterator it  = s.begin()=;
std::string::const_iterator end = s.end()=;
while (boost::regex_search(it,end,m,reg)
{
    // m[1/2] indicates whether new or delete was found
    m[1].matched ? ++new_counter : ++ deleteCounter;
    it = m[0].second; // m[0] is a reference to the submatch, continue
                      // searching at the end of that submatch
}
Replacing
// Replace colour with color and preserve the found case
// i.e. Colour and colour should be treated correctly
bost::regex reg (“(Colo)(u)(r)”,               // use three subexpressions
    boost::regex::icase | boost::regex::perl); // ignore case
std::string s = “Colour, colours, color, colourize”;
// the matched expression is replaced with the
// first and third subexpression
s=boost::regex_replace(s,reg,”$1$3”);
Elementarbeispiel Any
boost::any a;
// Any type can be stored
a = std::string(A string”);
a = 43;
a = 3.14;
// accessing the stored value requires to
// know the correct type
double d = boost::any_cast<double>(a);
// Reactions when assuming the wrong type:
// using pointer syntax
int* pVal = boost::any_cast<int>(&a); // in this case 0 is returned
// using const reference 
int val = boost::any_cast<int>(a); // exception boost::bad_any_cast
// Requesting the type and comparing it
if (typeid(int)==a.type())
{/* access as int type is possible */}
STL-Container mit heterogenen Elementen
class A{};
class B{};
std::vector<boost::any> vec;
// Store arbitrary objects within the vector
vec.push_back (A());
vec.push_back (B());
vec.push_back (boost::shared_ptr<B>(new B));
vec.push_back (std::string(“Hallo”));
vec.push_back (4711);
vec.push_back (3.14);
// Remark: You can build a function to process the elements stored
// within the vector. The function simply has to check for the types it
// is able to process (e.g. using pointer syntax see above) and leave the
// other types unhandled
// generic helper function to test the stored type
template <typename T>
bool Contains (const boost::any& a)
{return typeid(T)==a.type();}
Elementarbeispiel variant
// allow three types for your variant typedef boost::variant<int,std::string,double> MyVariant; MyVariant myVar; // default constructed int = first type MyVariant myVar2 (Hello”); // variant containing type string // dynamically change the type myVar2 = 2.53; myVar2 = 47; // accessing the stored values assert(boost::get<int>(myVar2)==47); // wrong type would cause exception boost::bad_get) int* pVal=boost::get<int>(&myVar2); assert(pVal &&(*pVal==47)) // wrong type would cause return of NULL pointer)
Zugriff über Visitor (mit compile time check)
// Define a visitor class containing a function call operator for each
// type within your variant you want to access.
// Remark: use reference syntax to avoid unwanted conversions (e.g.
// from char to int)
class PrintVisitor : public boost::static_visitor<void>
{
public:
    void operator()(int& i) const
    {std::cout << “int val “ << i << ‘\n’;}
    void operator()(double& d) const
    {std::cout << “double val “ << d << ‘\n’;}
};
PrintVisitor v;
myVar = 46;
boost::apply_visitor(v,myVar);
myVar = 4.5;
boost::apply_visitor(v,myVar);
myVar = “Any text”;
boost::apply_visitor(v,myVar); // Compile ERROR, because type string
                               // is not supported by PrintVisitor
// Possible extension to PrintVisitor for generically support
// of output for all types compatible with << operator
class PrintVisitor (see above)
{
    // specific operators for some types see above
    // generic operator for all other types
    template <typename T> void operator()(T& t) const
    {std::cout << t << '\n';}
}
tuple - Elementarbeispiel
boost::tuple<int,double,std::string> triple (42, 3.14, “Hello”); // Access the values int i = boost::get<0>(triple); double d = boost::get<1>(triple);
tuple als Returnwert
boost::tuple<int,int> Calculate (int x)
{return boost::make_tuple(x+3, x*x);}
boost::tuple<int,int> result = Calculate(17);
int resultX = result.get<0>();
int resultY = result.get<1>();
// directly connect to result variables
boost::tie(resultX, resultY) = Calculate(19);
// here the results will be available without further asking;
// instead of making copies references are used;
// is the same as make_tuple(ref(resultx), ref(resultY) = ..
tuple - generisches Programmieren, for_each
//--- Definition of for_each_element ---
// for the last element within the tuple (is always null_type)
// do nothing
template <typename Function>
void for_each_element (
    const boost::tuples::null_type&, Function) {}
// for the preceeding elements call the given function
template <typename Tuple, typename Function>
void for_each_element (Tuple& t, Function func)
{
    func(t.get_head()); // call func for the first element
    for_each_elemnt(t.get_tail(), func); // recursively process
                                         // the rest of the tuple
}
//--- FuncObjects for output ---
struct PrintAll
{
    template <typename T> void operator()(const T& t)
    {std::cout << t <<’\n’;}
}
template typename T>
struct PrintSelectedType
{
    // print the selected type
    void operator()(const T& t)
    {std::cout << t <<’\n’;}
    // ignore all other types (discarding overload)
    template <typename U>
    void operator()(const U&){}
}
//--- Example ---
boost::tuple<int,short,double> nums(1,2,3.14);
for_each_element(nums,PrintAll()); // writes all numbers
for_each_element(nums,PrintSelectedType<double>()); // writes only the
                                                    // last number