Regex Summary That regular expressions are useful and important is not disputed, and this library brings terrific regex power to C++. Traditionally, users have had few choices besides using the POSIX C APIs for regular expressions. For text-processing validation tasks, regular expressions are much more scalable and reliable than handcrafted parsers. For searching and replacing, there are a number of problems that are very elegantly solved using regular expressions, but virtually impossible to solve without them. Boost.Regex is a powerful library so it has not been possible to cover all of it in this chapter. Similarly, the great expressiveness and range of application of regular expressions necessarily means that this chapter offers little more than an introduction to them. These topics could easily fill a separate book. To learn more, study the online documentation for Boost.Regex and pick up a book on regular expressions (consult the Bibliography for suggestions). Despite the power of Boost.Regex, and the breadth and depth of regular expressions, even complete neophytes can use regular expressions effectively with this library. For programmers who have selected other programming languages due to C++'s lack of support for regular expressions, welcome home. Boost.Regex is not the only regular expression library available for C++ programmers, but it is certainly one of the best. It's easy to use and fast as lightning when matching your regular expressions. Use it as often as you can. The author of Boost.Regex is Dr. John Maddock. How Does the Any Library Improve Your Programs? Typesafe storage and safe retrieval of arbitrary types A means to store heterogeneous types in Standard Library containers Types are being passed through layers that need not know anything about the types The Any library provides a type, any, that allows for storage of any type for later retrieval without loss of type safety. It is like a variant type on steroids: It will hold any type, but you have to know the type to retrieve the value. There are times when you need to store unrelated types in the same container. There are times when certain code only cares about conveying data from one point to another without caring about the data's type. At face value, it is easy to do those things. They can be done with an indiscriminate type such as void*. They can be done using a discriminated union. There are numerous variant types available that rely on some type tag mechanism. Unfortunately, all of these suffer from a lack of type safety, and only in the most controlled situations should we ever purposely defeat the type system. The Standard Library containers are parameterized on the type they contain, which poses a seemingly impossible challenge for storing elements of heterogeneous types in them. Fortunately, the cure doesn't have to be spelled void*, because the Any library allows you to store objects of different types for later retrieval. There is no way to get to the contained value without knowing its exact type, and thus, type safety is preserved. When designing frameworks, it isn't possible to know in advance about the types that will be used together with the framework classes. A common approach is to require the clients of the framework to adapt a certain interface, or inherit from base classes provided by the framework. This is reasonable, because the framework probably needs to communicate with various higher-level classes in order to be useful. There are, however, situations where the framework stores or otherwise accepts types that it doesn't need to (or can) know anything about. Rather than violating the type system and go with the void* approach, the framework can use any. How Does Any Fit with the Standard Library? One important property of Any is that it provides the capability to store objects of heterogeneous types in Standard Library containers. It is also a sort of variant data type, which is something sorely needed, and currently missing, in the C++ Standard Library. Any Header: "boost/any.hpp" The class any allows typesafe storage and retrieval of arbitrary types. Unlike indiscriminate types, any preserves the type, and actually does not let you near the stored value without knowing the correct type. Of course, there are means for querying for the type, and testing alternatives for the contained value, but in the end, the caller must know the exact type of the value in an any object, or any denies access. Think of any as a locked safe. Without the proper key, you cannot get in. any requires the following of the types it stores: CopyConstructible It must be possible to copy the type. Non-throwing destructor As all destructors should be! Assignable For the strong exception guarantee (types that aren't assignable can still be used with any, but without the strong guarantee). This is the public interface of any: namespace boost { class any { public: any(); any(const any&); template<typename ValueType> any(const ValueType&); ~any(); any& swap(any &); any& operator=(const any&); template<typename ValueType> any& operator=(const ValueType&); bool empty() const; const std::type_info& type() const; }; } Members any(); The default constructor creates an empty instance of anythat is, an any that doesn't contain a value. Of course, there is no way of retrieving the value of an empty any, because no value exists. any(const any& other); Creates a distinct copy of an existing any object. The value that is contained in other is copied and stored in this. template<typename ValueType> any(const ValueType&); This templated constructor stores a copy of the argument of type ValueType passed to the constructor. The argument is a const reference, so it is legal to pass a temporary object to be stored in any. Note that the constructor is not explicit, which would make typical uses of any awkward and would not impart additional safety. ~any(); The destructor destroys the contained value, but note that because the destruction of a raw pointer does not invoke operator delete or operator delete[] on the pointer, you should always wrap raw pointers in smart pointers such as shared_ptr (see "Library 1: Smart_ptr 1") when using pointers with any. any& swap(any& other); Exchanges the values stored by the two any objects. any& operator=(const any& other); Discards the stored value, if the instance of any is not empty, and stores a copy of the value in other. template<typename ValueType> any& operator=(const ValueType& value); Discards the stored value, if the instance of any is not empty, and stores a copy of value, which can be of an arbitrary type that fulfills any's requirements. bool empty() const; Indicates whether an instance of any currently has a value, regardless of what that value is. Thus, when an any holds a pointer, empty returns false even if the pointer value is null. const std::type_info& type() const; Indicates the type of the stored value. If the any is empty, the type is void. Free Functions template<typename ValueType> ValueType any_cast(const any& operand); any_cast gives you access to the value stored in an any. The argument is the any whose value is to be retrieved. If the type ValueType does not correspond to the type of the stored value, any throws a bad_any_cast exception. Note that the syntax is like that of dynamic_cast. template<typename ValueType> const ValueType* any_cast(const any* operand); This overloaded any_cast takes a pointer to any, and returns a pointer to the stored value. If the type in the any isn't ValueType , a null pointer is returned. Note, again, that the syntax is like that of dynamic_cast. template<typename ValueType> ValueType* any_cast(any* operand); This overloaded any_cast is similar to the preceding version, but whereas the previous version used const-qualified pointers for return type and argument type, this version doesn't. Exceptions bad_any_cast This exception is thrown when trying to cast an any object to a type other than the type stored in the any. bad_any_cast is derived from std::bad_cast. Note that when calling any_cast with a pointer argument, no exception is thrown (similar to how dynamic_cast with pointer types return the null pointer), whereas dynamic_cast to reference types throws an exception on failure. . the constructor is not explicit, which would make typical uses of any awkward and would not impart additional safety. ~any(); The destructor destroys the contained value, but note that because