Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

Using in a library

Use in a header only library
Use in a non-header only library
Support for naming library variants and testing all valid possibilities

Using CXXD in a library presents a number of situations which do not occur when using CXXD in an executable. These situations will be discussed in this part of the documentation.

When CXXD is used in a header only library the most important thing is to document for the end-user of the library which mods are being used and whether each mod which is being used is using the dual library, or has been overriden to use a single choice for that mod.

Specifying the interface

When using a particular Boost library within another library, let's call it MyLibrary, a class interface in a MyLibrary header file might look like:

// Header file MyHeader.hpp
#include <boost/regex.hpp>
class MyClass
    {
    public:
    void MyFunction(boost::regex &);
    ... // other functionality
    };

Documentation for MyClass::MyFunction would specify that it takes a single parameter which is a reference to a boost::regex object.

A user of MyLibrary's MyClass functionality might then look like:

#include <MyHeader.hpp>
MyClass an_object;
boost::regex a_regular_expression(...some regular expression etc.);
an_object.MyFunction(a_regular_expression);
// more code etc.

Similarly when using a C++ standard library equivalent to a particular Boost library within another library, let's call it again MyLibrary, a class interface in a MyLibrary header file might look like:

// Header file MyHeader.hpp
#include <regex>
class MyClass
    {
    public:
    void MyFunction(std::regex &);
    ... // other functionality
    };

Documentation for MyClass::MyFunction would specify that it takes a single parameter which is a reference to a std::regex object.

A user of MyLibrary's MyClass functionality might then look like:

#include <MyHeader.hpp>
MyClass an_object;
std::regex a_regular_expression(...some regular expression etc.);
an_object.MyFunction(a_regular_expression);
// more code etc.

Given these examples of using a Boost library or its C++ standard equivalent in another library we can then see how this works for creating an interface using CXXD in an example 'MyLibrary'. Our CXXD example would look like:

// Header file MyHeader.hpp
#include <boost/cxx_dual/regex.hpp>
class MyClass
    {
    public:
    void MyFunction(cxxd_regex_ns::regex &);
    ... // other functionality
    };

Documentation for MyClass::MyFunction would specify that it takes a single parameter which is a reference to a cxxd_regex_ns::regex object, where 'cxxd_regex_ns' represents the namespace being used.

A user of MyLibrary's MyClass functionality might look like:

#include <MyHeader.hpp>
MyClass an_object;
cxxd_regex_ns::regex a_regular_expression(...some regular expression etc.);
an_object.MyFunction(a_regular_expression);
// more code etc.

As in all these similar situations, once the user understands that 'cxxd_regex_ns' represents the name of a namespace, functionality using MyLibrary's MyClass functionality could also be coded as:

#include <MyHeader.hpp>
using namespace cxxd_regex_ns;
MyClass an_object;
regex a_regular_expression(...some regular expression etc.);
an_object.MyFunction(a_regular_expression);
// more code etc.

The important thing here is that the user of MyFunction understands that 'cxxd_regex_ns' should be used to designate the namespace without assuming that either Boost or the C++ standard equivalent of the regex library is being used. Obviously the same goes for any other mod, where the CXXD namespace alias for any particular mod should be consistently used as opposed to making any assumptions about whether the Boost version or the C++ standard of a mod is being chosen. As long as the documentation for an interface using CXXD specifies this usage the end-user of such an interface should be able to use it correctly.

Overriding a mod in a library

As explained when generally discussing the purpose of the overriding macros it is usually foolish for code to override its own interface(s) which use CXXD, rather than simply dropping a CXXD dual library in order to directly use either a Boost library or its standard C++ equivalent library in the interface.

Overriding macros for a mod in a library should normally occur when that mod is being used in a second library and the second library doing the overriding consistently uses the Boost or C++ standard dual library for that mod otherwise.

Given in OtherLibrary:

// Header file OtherHeader.hpp
#include <boost/cxx_dual/regex.hpp>
class OtherClass
    {
    public:
    void OtherFunction(cxxd_regex_ns::regex &);
    ... // other functionality
    };

let us suppose that MyLibrary consistently uses the Boost regex library in other places. Now MyLibrary wants to use OtherLibrary's OtherClass::OtherFunction functionality with a Boost regex rather than let CXXD choose the default library for the regex mod. The code for using OtherLibrary's OtherClass::OhterFunction functionality with a Boost regex in MyLibrary's own header file might look like:

// Header file MyHeader.hpp
#define CXXD_REGEX_USE_BOOST
#include <Otherheader.hpp>
class MyClass
    {
    public:
    void MyFunction(boost::regex &my_regex)
        {
        OtherClass oc;
        oc.OtherFunction(my_regex);
        ... // other functionality
        }
    ... // other functionality
    };

Subsequently in this case if MyLibrary's MyClass functionality is meant to be used by another library or executable the documentation should state that the regex mod has been overridden to use boost::regex, and therefore MyHeader.hpp should be included before any other header file which might include the CXXD regex header. The reason for this was explained when discussing mod consistency, where including a CXXD header more than once could lead to a preprocessing error if the CXXD header is subsequently overridden opposite to its initial default choice.

What is also important in a library is that the overriding macro be defined within the public header file of the library. In our example just above the

#define CXXD_REGEX_USE_BOOST

overriding macro must be in the header file itself so that any other code which uses the library, and includes the MyHeader.hpp file, picks up the override. This is different from an executable where an overriding macro could be passed on the command line when a particular TU is being compiled.


PrevUpHomeNext