Section 10.4.  C++ as the Host Language
Team LiB
Previous Section Next Section

10.4. C++ as the Host Language

Fortunately for us, C++ turns out to be a one-of-a-kind language for implementing DSELs. Its multiparadigm heritage has left C++ bristling with tools we can use to build libraries that combine syntactic expressivity with runtime efficiency. In particular, C++ provides

  • A static type system

  • The ability to achieve near-zero abstraction penalty[3]

    [3] With current compilers, avoiding abstraction penalties sometimes requires a great deal of attention from the programmer. Todd Veldhuizen has described a technique called "guaranteed optimization," in which various kinds of abstraction can be applied at will, with no chance of hurting performance [Veld04].

  • Powerful optimizers

  • A template system that can be used to

    generate new types and functions

    perform arbitrary computations at compile time

    dissect existing program components (e.g., using the type categorization metafunctions of the Boost Type Traits library)

  • A macro preprocessor providing (textual) code generation capability orthogonal to that of templates (see Appendix A)

  • A rich set of built-in symbolic operators (48!)many of which have several possible spellingsthat can be overloaded with practically no limitations on their semantics

Table 10.1 lists the syntactic constructs provided by operator overloading in C++. Table entries with several lines show some little-known alternative spellings for the same tokens.

Table 10.1. C++ Overloadable Operator Syntaxes

+a

-a

a + b

a - b

++a

--a

a++

a--

a * b

a / b

a % b

a, b

a & b
a
bitand b

a | b
a
bitor b

a ^ b
a ??' b
a
xor b

~a
??-a
compl a

a & & b
a
and b

a | | b
a
or b

a >> b

a << b

a > b

a < b

a >= b

a <= b

a == b

a != b
a
not_eq b

! a
not a

a = b

a += b

a -= b

a *= b

a /= b

a %= b

a &= b
a
and_eq b

a |= b
a
or_eq b

a ^= b
a
xor_eq b

a >>= b

a <<= b

*a

&a

a->name

a->*name

a [b]
a?? (b??)
a<:b:>

a (arguments)

new ctor-expr

delete a

  


The unique combination of these features in C++ has made possible a category of domain-specific libraries that are both efficient and syntactically close to languages one might build from scratch.[4] Moreover, these libraries can be written in pure C++, giving them important advantages over standalone DSLs, which require special compilers, editors, and other tools. In the following sections we'll discuss some examples, in each case focusing on the DSL's design rather than its implementation.

[4] Haskell is another language that certainly deserves mention when considering platforms for building DSELs. Haskell's strengths for DSEL construction overlap considerably with those of C++, and go even further in some areas. For example, Haskell programmers can define new operators with which to extend the built-in language syntax. Haskell's compilation model, however, tends to limit peak performance.

Namespace Names

Until now, we've been fairly disciplined about always prefixing names from namespace boost with boost:: and names from boost::mpl with mpl:: to avoid confusion. In this chapter only, to emphasize the "sugary" aspects of DSL syntax, we're going to omit namespace names from library identifiers, and trust you to guess where the names come from.


    Team LiB
    Previous Section Next Section