Tidy up tests, build scripts, and documentation:

* Concepts split up into individual files
* Function definitions moved to .ipp files
* Add more tests to fill gaps in coverage
* Fix documentation Xsl
This commit is contained in:
Vinnie Falco
2016-05-01 12:33:35 -04:00
parent 9e5e16c18d
commit 6d8c73cc52
92 changed files with 2915 additions and 1808 deletions

View File

@@ -103,6 +103,11 @@ WARN_LOGFILE =
# Configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = \
../include/beast/ \
../include/beast/http \
../include/beast/websocket \
../include/beast/doc_debug.hpp \
../include/beast/async_completion.hpp \
../include/beast/basic_streambuf.hpp \
../include/beast/bind_handler.hpp \
@@ -121,7 +126,7 @@ INPUT = \
../include/beast/websocket.hpp \
../include/beast/write_streambuf.hpp \
../include/beast/http/basic_headers.hpp \
../include/beast/http/basic_parser.hpp \
../include/beast/http/basic_parser_v1.hpp \
../include/beast/http/body_writer.hpp \
../include/beast/http/chunk_encode.hpp \
../include/beast/http/empty_body.hpp \

View File

@@ -186,7 +186,12 @@ documentation is based.
[include http.qbk]
[include websocket.qbk]
[include types.qbk]
[section:types Type Requirements]
[include core_types.qbk]
[include http_types.qbk]
[endsect]
[include design.qbk]
[section:quickref Quick Reference]
[xinclude quickref.xml]

118
doc/core_types.qbk Normal file
View File

@@ -0,0 +1,118 @@
[/
Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
]
[section:BufferSequence BufferSequence]
A `BufferSequence` is a type meeting either of the following requirements:
* [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/ConstBufferSequence.html [*`ConstBufferSequence`]]
* [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/MutableBufferSequence.html [*`MutableBufferSequence`]]
[endsect]
[section:stream Streams]
Stream types represent objects capable of performing synchronous or
asynchronous I/O. They are based on concepts from `boost::asio`.
[heading:Stream Stream]
A type modeling [*`Stream`] meets either or both of the following requirements:
* [link beast.types.stream.AsyncStream [*`AsyncStream`]]
* [link beast.types.stream.SyncStream [*`SyncStream`]]
[heading:AsyncStream AsyncStream]
A type modeling [*`AsyncStream`] meets the following requirements:
* [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/AsyncReadStream.html [*`AsyncReadStream`]]
* [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/AsyncWriteStream.html [*`AsyncWriteStream`]]
[heading:SyncStream SyncStream]
A type modeling [*`SyncStream`] meets the following requirements:
* [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/SyncReadStream.html [*`SyncReadStream`]]
* [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/SyncWriteStream.html [*`SyncWriteStream`]]
[endsect]
[section:Streambuf Streambuf]
In the table below:
* `X` denotes a class
* `a` denotes a value of type `X`
* `n` denotes a value convertible to `std::size_t`
* `U`, `T` denote unspecified types.
[table Streambuf requirements
[[operation] [type] [semantics, pre/post-conditions]]
[
[`X::const_buffers_type`]
[`T`]
[`T` meets the requirements for `ConstBufferSequence`.]
]
[
[`X::mutable_buffers_type`]
[`U`]
[`U` meets the requirements for `MutableBufferSequence`.]
]
[
[`a.commit(n)`]
[`void`]
[Moves bytes from the output sequence to the input sequence.]
]
[
[`a.consume(n)`]
[`void`]
[Removes bytes from the input sequence.]
]
[
[`a.data()`]
[`T`]
[Returns a list of buffers that represents the input sequence.]
]
[
[`a.prepare(n)`]
[`U`]
[Returns a list of buffers that represents the output sequence, with
the given size.]
]
[
[`a.size()`]
[`std::size_t`]
[Returns the size of the input sequence.]
]
[
[`a.max_size()`]
[`std::size_t`]
[Returns the maximum size of the `Streambuf`.]
]
[
[`read_size_helper(a, n)`]
[`std::size_t`]
[
Returns the suggested number of bytes to read into the output
sequence where `n` is an upper limit on this value. One possible
implementation is to return the number of bytes that may be prepared
without causing a dynamic allocation or `n`, whichever is smaller.
Calls to `read_size_helper` will be made without namespace
qualification, to allow the rules for argument dependent lookup to
take effect.
]
]
]
[endsect]

View File

@@ -8,7 +8,7 @@
[section:design Design choices]
The implementations are driven by business needs of cryptocurrency server
applications ([link https://ripple.com Ripple] written in C++. These
applications ([@https://ripple.com Ripple] written in C++. These
needs were not met by existing solutions so new code was written. The new
code tries to avoid design flaws encountered in the already-existing software
libraries:
@@ -194,8 +194,8 @@ start. Other design goals:
The WebSocket implementation [*does] provides support for shutting down
the TLS connection through the use of the ADL compile-time virtual functions
[link beast.ref.wsproto__teardown `teardown`] and
[link beast.ref.wsproto__async_teardown `async_teardown`]. These will
[link beast.ref.websocket__teardown `teardown`] and
[link beast.ref.websocket__async_teardown `async_teardown`]. These will
properly close the connection as per rfc6455 and overloads are available
for TLS streams. Callers may provide their own overloads of these functions
for user-defined next layer types.

View File

@@ -9,7 +9,7 @@
Beast.HTTP offers programmers simple and performant models of HTTP messages and
their associated operations including synchronous and asynchronous reading and
writing using Boost.Asio.
writing of messages in the HTTP/1 wire format using Boost.Asio.
The HTTP protocol is described fully in
[@https://tools.ietf.org/html/rfc2616 rfc2616]
@@ -25,20 +25,43 @@ compliant with the Hypertext Transfer Protocol and the supplements that
follow. Unfortunately reliable implementations or industry standards do not
exist in C++.
Beast.HTTP is built on Boost.Asio and uses HTTP parser from NodeJS, which is
extensively field tested and exceptionally robust. A proposal to add networking
functionality to the C++ standard library, based on Boost.Asio, is under
consideration by the standards committee. Since the final approved networking
interface for the C++ standard library will likely closely resemble the current
interface of Boost.Asio, it is logical for Beast.HTTP to use Boost.Asio as its
network transport.
Beast.HTTP is built on Boost.Asio and uses its own robust header-only HTTP/1
message parser modeled after the nodejs http-parser (written in C). A proposal
to add networking functionality to the C++ standard library, based on
Boost.Asio, is under consideration by the standards committee. Since the final
approved networking interface for the C++ standard library will likely closely
resemble the current interface of Boost.Asio, it is logical for Beast.HTTP to
use Boost.Asio as its network transport.
[heading Scope]
[endsect]
The scope of this library is meant to include only the functionality of
modeling the HTTP message, serializing and deserializing the message, and
sending and receiving messages on sockets or streams. It is designed to
be a building block for creating higher level abstractions.
[section:scope Scope]
This library is designed to be a building block for creating higher level
libraries. It is not designed to be end-user facing. There is no convenient
class that implements the core of a web server, nor is there a convenient
class to quickly perform common operations such as fetching a file or
connecting and retrieving a document from a secure connection. These
use-cases are important. But this library does not try to do that. Instead,
it offers primitives that can be used to build those user-facing algorithms.
A HTTP message (referred to hereafter as "message") contains request or
response specific attributes, a series of zero or more name/value pairs
(collectively termed "headers"), and a series of octets called the message
body which may be zero in length. The HTTP protocol defines the client and
server roles: clients send messages called requests and servers send back
messages called responses. `http::message` models both requests and responses.
Beast aims to offer this functionality:
* [*Model]: Provide a universal HTTP message class model.
* [*Build]: Construct a new message and manipulate its contents.
* [*Parse]: Deserialize a message from a network or memory stream in HTTP/1 wire format.
* [*Serialize]: Serialize a message into a network or memory stream in HTTP/1 wire format.
[note The documentation which follows assumes familiarity with
both Boost.Asio and the HTTP protocol specification described in
@@ -59,35 +82,17 @@ both Boost.Asio and the HTTP protocol specification described in
```
]
A HTTP message (referred to hereafter as "message") contains a request or
response line, a series of zero or more name/value pairs (collectively
termed "headers"), and a series of octets called the message body which may
be zero in length. The HTTP protocol defines the client and server roles:
clients send messages called requests and servers send back messages called
responses. `http::message` models both requests and responses. The library
provides interfaces to perform these operations on messages:
* [*Parse] a new message from a series of octets.
* [*Assemble] a new message from scratch or from an existing message.
* [*Serialize] a message into a series of octets.
* [*Read] a message from a stream. This can be thought of as a compound
operation; a network read, followed by a [*parse].
* [*Write] a message to a stream. This can be thought of as a compound
operation: a [*serialize] followed by a network write.
In the paragraphs that follow we describe simple interfaces that will serve
the majority of users looking merely to interact with a HTTP server, or
handle simple HTTP requests from clients. Subsequent sections cover the
message model in more depth, for advanced applications.
In the paragraphs that follow we describe the available interfaces for
performing typical operations such as interacting with a HTTP server
or handling simple requests. Subsequent sections cover the message model
and its customization points in more depth, for advanced applications.
[heading Declarations]
To do anything, a message must be declared. The message class template
requires at mininum, a bool indicating whether the message is a request
requires at mininum, a value indicating whether the message is a request
(versus a response), and a `Body` type. The choice of `Body` determines the
kind of container used to represent the message body. Here we will
declare a request that has a `std::string` for the body container:

View File

@@ -5,8 +5,6 @@
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
]
[section:types Type Requirements]
[section:Body Body]
@@ -57,10 +55,10 @@ In this table:
[section:BufferSequence BufferSequence]
A `BufferSequence` meets [*one of] the following requirements:
A `BufferSequence` is a type meeting either of the following requirements:
* `ConstBufferSequence`
* `MutableBufferSequence`
* [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/ConstBufferSequence.html [*`ConstBufferSequence`]]
* [@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/MutableBufferSequence.html [*`MutableBufferSequence`]]
[endsect]
@@ -223,7 +221,7 @@ In this table:
* `m` denotes a value of type `message const&` where
`std::is_same<decltype(m.body), Body::value_type>:value == true`.
* `rc` is an object of type [link beast.reference.http__resume_context resume_context].
* `rc` is an object of type [link beast.ref.http__resume_context resume_context].
* `ec` is a value of type `error_code&`.
@@ -373,74 +371,3 @@ public:
[endsect]
[section:Stream Stream]
A `Stream` meets the following requirements:
* `SyncReadStream`
* `SyncWriteStream`
* `AsyncReadStream`
* `AsyncWriteStream`
[endsect]
[section:Streambuf Streambuf]
In the table below, `X` denotes a class, `a` denotes a value
of type `X`, `n` denotes a value convertible to `std::size_t`,
and `U` and `T` denote unspecified types.
[table Streambuf requirements
[[operation] [type] [semantics, pre/post-conditions]]
[
[`X::const_buffers_type`]
[`T`]
[`T` meets the requirements for `ConstBufferSequence`.]
]
[
[`X::mutable_buffers_type`]
[`U`]
[`U` meets the requirements for `MutableBufferSequence`.]
]
[
[`a.commit(n)`]
[`void`]
[Moves bytes from the output sequence to the input sequence.]
]
[
[`a.consume(n)`]
[`void`]
[Removes bytes from the input sequence.]
]
[
[`a.data()`]
[`T`]
[Returns a list of buffers that represents the input sequence.]
]
[
[`a.prepare(n)`]
[`U`]
[Returns a list of buffers that represents the output sequence, with
the given size.]
]
[
[`a.size()`]
[`std::size_t`]
[Returns the size of the input sequence.]
]
[
[`a.max_size()`]
[`std::size_t`]
[Returns the maximum size of the `Streambuf`.]
]
]
[endsect]
[endsect]

View File

@@ -30,7 +30,7 @@
<bridgehead renderas="sect3">Classes</bridgehead>
<simplelist type="vert" columns="1">
<member><link linkend="beast.ref.http__basic_headers">basic_headers</link></member>
<member><link linkend="beast.ref.http__basic_parser">basic_parser</link></member>
<member><link linkend="beast.ref.http__basic_parser_v1">basic_parser_v1</link></member>
<member><link linkend="beast.ref.http__basic_streambuf_body">basic_streambuf_body</link></member>
<member><link linkend="beast.ref.http__empty_body">empty_body</link></member>
<member><link linkend="beast.ref.http__error_code">error_code</link></member>
@@ -42,7 +42,7 @@
</simplelist>
<bridgehead renderas="sect3">Type Traits</bridgehead>
<simplelist type="vert" columns="1">
<member><link linkend="beast.ref.http__is_Body">is_Body</link></member>
<member><link linkend="beast.ref.http__is_Parser">is_Parser</link></member>
</simplelist>
</entry>
<entry valign="top">
@@ -50,9 +50,14 @@
<simplelist type="vert" columns="1">
<member><link linkend="beast.ref.http__async_read">async_read</link></member>
<member><link linkend="beast.ref.http__async_write">async_write</link></member>
<member><link linkend="beast.ref.http__prepare">prepare</link></member>
<member><link linkend="beast.ref.http__read">read</link></member>
<member><link linkend="beast.ref.http__write">write</link></member>
</simplelist>
<bridgehead renderas="sect3">Constants</bridgehead>
<simplelist type="vert" columns="1">
<member><link linkend="beast.ref.http__connection">connection</link></member>
</simplelist>
<bridgehead renderas="sect3">Concepts</bridgehead>
<simplelist type="vert" columns="1">
<member><link linkend="beast.types.Body">Body</link></member>
@@ -66,7 +71,6 @@
<bridgehead renderas="sect3">Classes</bridgehead>
<simplelist type="vert" columns="1">
<member><link linkend="beast.ref.websocket__close_reason">close_reason</link></member>
<member><link linkend="beast.ref.websocket__static_string">static_string</link></member>
<member><link linkend="beast.ref.websocket__stream">stream</link></member>
</simplelist>
<bridgehead renderas="sect3">Options</bridgehead>
@@ -119,6 +123,7 @@
<member><link linkend="beast.ref.prepared_buffers">prepared_buffers</link></member>
<member><link linkend="beast.ref.static_streambuf">static_streambuf</link></member>
<member><link linkend="beast.ref.static_streambuf_n">static_streambuf_n</link></member>
<member><link linkend="beast.ref.static_string">static_string</link></member>
<member><link linkend="beast.ref.streambuf">streambuf</link></member>
<member><link linkend="beast.ref.streambuf_readstream">streambuf_readstream</link></member>
</simplelist>
@@ -128,20 +133,24 @@
<simplelist type="vert" columns="1">
<member><link linkend="beast.ref.bind_handler">bind_handler</link></member>
<member><link linkend="beast.ref.buffer_cat">buffer_cat</link></member>
<member><link linkend="beast.ref.consumed_buffers">consumed_buffers</link></member>
<member><link linkend="beast.ref.prepare_buffer">prepare_buffer</link></member>
<member><link linkend="beast.ref.prepare_buffers">prepare_buffers</link></member>
<member><link linkend="beast.ref.to_string">to_string</link></member>
<member><link linkend="beast.ref.write">write</link></member>
</simplelist>
</entry>
<entry valign="top">
<bridgehead renderas="sect3">Type Traits</bridgehead>
<simplelist type="vert" columns="1">
<member><link linkend="beast.ref.is_AsyncReadStream">is_AsyncReadStream</link></member>
<member><link linkend="beast.ref.is_AsyncWriteStream">is_AsyncWriteStream</link></member>
<member><link linkend="beast.ref.is_AsyncStream">is_AsyncStream</link></member>
<member><link linkend="beast.ref.is_BufferSequence">is_BufferSequence</link></member>
<member><link linkend="beast.ref.is_CompletionHandler">is_CompletionHandler</link></member>
<member><link linkend="beast.ref.is_ConstBufferSequence">is_ConstBufferSequence</link></member>
<member><link linkend="beast.ref.is_Handler">is_Handler</link></member>
<member><link linkend="beast.ref.is_MutableBufferSequence">is_MutableBufferSequence</link></member>
<member><link linkend="beast.ref.is_Streambuf">is_Streambuf</link></member>
<member><link linkend="beast.ref.is_SyncReadStream">is_SyncReadStream</link></member>
@@ -153,8 +162,30 @@
<bridgehead renderas="sect3">Concepts</bridgehead>
<simplelist type="vert" columns="1">
<member><link linkend="beast.types.BufferSequence">BufferSequence</link></member>
<member><link linkend="beast.types.Stream">Stream</link></member>
<member><link linkend="beast.types.stream.AsyncStream">AsyncStream</link></member>
<member><link linkend="beast.types.stream.Stream">Stream</link></member>
<member><link linkend="beast.types.Streambuf">Streambuf</link></member>
<member><link linkend="beast.types.stream.SyncStream">SyncStream</link></member>
</simplelist>
</entry>
</row>
</tbody>
</tgroup>
<tgroup cols="1">
<colspec colname="a"/>
<thead>
<row>
<entry valign="center" namest="a" nameend="a">
<bridgehead renderas="sect2">Diagnostic</bridgehead>
</entry>
</row>
</thead>
<tbody>
<row>
<entry valign="top">
<simplelist type="vert" columns="1">
<member><link linkend="beast.ref.doc_debug">doc_debug</link></member>
<member><link linkend="beast.ref.nested__nested_doc_debug">nested_doc_debug</link></member>
</simplelist>
</entry>
</row>

View File

@@ -43,6 +43,7 @@
<xsl:when test="@kind='class' or @kind='struct'">
<xsl:if test="
contains(compoundname, 'beast::') and
not(contains(compoundname, 'boost::')) and
not(contains(compoundname, '::detail')) and
not(contains(compoundname, 'rfc2616')) and
not(contains(@prot, 'private'))">
@@ -61,7 +62,6 @@
<xsl:text>&#xd;[endsect]</xsl:text>
</xsl:template>
<!--========== Utilities ==========-->
<xsl:template name="strip-beast-ns">
@@ -73,6 +73,9 @@
<xsl:when test="contains($name, 'beast::')">
<xsl:value-of select="substring-after($name, 'beast::')"/>
</xsl:when>
<xsl:when test="$name = 'beast'">
<xsl:text></xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$name"/>
</xsl:otherwise>
@@ -108,6 +111,38 @@
</xsl:choose>
</xsl:template>
<xsl:template name="cleanup-param">
<xsl:param name="name"/>
<xsl:variable name="clean">
<xsl:value-of select="$name"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="' *' = substring($clean, string-length($clean) - 1)">
<xsl:value-of select="substring($clean, 1, string-length($clean) - 2)"/>
<xsl:text>*</xsl:text>
</xsl:when>
<xsl:when test="' &amp;' = substring($clean, string-length($clean) - 1)">
<xsl:value-of select="substring($clean, 1, string-length($clean) - 2)"/>
<xsl:text>&amp;</xsl:text>
</xsl:when>
<xsl:when test="' &amp;...' = substring($clean, string-length($clean) - 4)">
<xsl:value-of select="substring($clean, 1, string-length($clean) - 5)"/>
<xsl:text>&amp;...</xsl:text>
</xsl:when>
<xsl:when test="' &amp;&amp;' = substring($clean, string-length($clean) - 2)">
<xsl:value-of select="substring($clean, 1, string-length($clean) - 3)"/>
<xsl:text>&amp;&amp;</xsl:text>
</xsl:when>
<xsl:when test="' &amp;&amp;...' = substring($clean, string-length($clean) - 5)">
<xsl:value-of select="substring($clean, 1, string-length($clean) - 6)"/>
<xsl:text>&amp;&amp;...</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$clean"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="cleanup-type">
<xsl:param name="name"/>
<xsl:variable name="type">
@@ -124,20 +159,22 @@
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="$type='ConstBufferSequence'">
<xsl:text>``[link beast.ref.ConstBufferSequence ['ConstBufferSequence]]``</xsl:text>
</xsl:when>
<xsl:when test="$type='implementation_defined'">
<xsl:text>``['implementation-defined]``</xsl:text>
</xsl:when>
<xsl:when test="$type='void_or_deduced'">
<xsl:text>``[link beast.ref.asynchronous_operations.return_type_of_an_initiating_function ['void-or-deduced]]``</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$type"/>
</xsl:otherwise>
</xsl:choose>
<xsl:variable name="cleaned">
<xsl:choose>
<xsl:when test="$type='implementation_defined'">
<xsl:text>``['implementation-defined]``</xsl:text>
</xsl:when>
<xsl:when test="$type='void_or_deduced'">
<xsl:text>``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/asynchronous_operations.html#boost_asio.reference.asynchronous_operations.return_type_of_an_initiating_function ['void-or-deduced]]``</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$type"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:call-template name="cleanup-param">
<xsl:with-param name="name" select="$cleaned"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="make-id">
@@ -260,8 +297,9 @@
<!--========== Markup ==========-->
<xsl:template match="para" mode="markup">
<xsl:apply-templates mode="markup"/>
<xsl:text>&#xd;</xsl:text>
<xsl:value-of select="$newline"/>
<xsl:apply-templates mode="markup"/>
<xsl:value-of select="$newline"/>
</xsl:template>
<xsl:template match="para" mode="markup-nested">
@@ -391,6 +429,8 @@
<xsl:apply-templates mode="markup"/>
</xsl:when>
<xsl:when test="@kind='see'">
<xsl:text>[heading See Also]&#xd;</xsl:text>
<xsl:apply-templates mode="markup"/>
</xsl:when>
<xsl:when test="@kind='note'">
<xsl:text>[heading Remarks]&#xd;</xsl:text>
@@ -536,12 +576,13 @@
</xsl:template>
<xsl:template match="ref[@kindref='compound']" mode="markup">
<xsl:variable name="name">
<xsl:value-of select="."/>
</xsl:variable>
<xsl:choose>
<xsl:when test="contains(@refid, 'asio') or contains($name, 'asio::')">
<xsl:when test="contains(@refid, 'beast')">
<xsl:variable name="dox-ref-id" select="@refid"/>
<xsl:variable name="ref-name">
<xsl:call-template name="strip-beast-ns">
@@ -554,6 +595,14 @@
<xsl:with-param name="name" select="$ref-name"/>
</xsl:call-template>
</xsl:variable>
<!--<xsl:text>|1|</xsl:text>-->
<!--
<xsl:text>[role red ref-name='</xsl:text>
<xsl:value-of select="$ref-name"/>
<xsl:text>'|ref-id='</xsl:text>
<xsl:value-of select="$ref-id"/>
<xsl:text>']|</xsl:text>
-->
<xsl:text>[link beast.ref.</xsl:text>
<xsl:value-of select="$ref-id"/>
<xsl:text> `</xsl:text>
@@ -561,89 +610,106 @@
<xsl:text>`]</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>`</xsl:text>
<xsl:text>[role red |1|</xsl:text>
<xsl:value-of select="."/>
<xsl:text>`</xsl:text>
<xsl:text>]</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="ref[@kindref='member']" mode="markup">
<xsl:variable name="name">
<xsl:value-of select="."/>
</xsl:variable>
<xsl:variable name="dox-ref-id" select="@refid"/>
<xsl:variable name="memberdefs" select="/doxygen//compounddef/sectiondef/memberdef[@id=$dox-ref-id]"/>
<xsl:variable name="def-kind" select="($memberdefs)/../../@kind"/>
<xsl:variable name="sec-kind" select="($memberdefs)/../@kind"/>
<xsl:choose>
<xsl:when test="contains(@refid, 'beast') and count($memberdefs) &gt; 0">
<xsl:variable name="dox-compound-name" select="($memberdefs)[1]/../../compoundname"/>
<xsl:variable name="dox-name" select="($memberdefs)[1]/name"/>
<xsl:variable name="ref-name">
<xsl:call-template name="strip-beast-ns">
<xsl:with-param name="name" select="$dox-compound-name"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="ref-id">
<xsl:call-template name="make-id">
<xsl:with-param name="name" select="$ref-name"/>
</xsl:call-template>
</xsl:variable>
<!--<xsl:text>|2|</xsl:text>-->
<!--
<xsl:text>[role red def-kind='</xsl:text>
<xsl:value-of select="$def-kind"/>
<xsl:text>', sec-kind='</xsl:text>
<xsl:value-of select="$sec-kind"/>
<xsl:text>', ref-id='</xsl:text>
<xsl:value-of select="$ref-id"/>
<xsl:text>'] </xsl:text>
-->
<xsl:choose>
<xsl:when test="$def-kind = 'namespace'">
<xsl:text>[link beast.ref.</xsl:text>
<xsl:choose>
<xsl:when test="string-length($ref-id) &gt; 0">
<xsl:value-of select="concat($ref-id,'__',$dox-name)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$dox-name"/>
</xsl:otherwise>
</xsl:choose>
<xsl:text> `</xsl:text>
<xsl:value-of name="text" select="$dox-name"/>
<xsl:text>`]</xsl:text>
</xsl:when>
<xsl:when test="$def-kind = 'class' or $def-kind = 'struct'">
<xsl:text>[link beast.ref.</xsl:text>
<xsl:value-of select="concat($ref-id,'.',$dox-name)"/>
<xsl:text> `</xsl:text>
<xsl:value-of name="text" select="$name"/>
<xsl:text>`]</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>[role red </xsl:text>
<xsl:value-of select="$name"/>
<xsl:text>]</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:text>[role red </xsl:text>
<xsl:value-of select="$name"/>
<xsl:text>]</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="ref[@kindref='compound']" mode="markup-nested">
<xsl:variable name="name">
<xsl:value-of select="."/>
</xsl:variable>
<xsl:choose>
<xsl:when test="contains(@refid, 'asio') or contains($name, 'asio::')">
<xsl:variable name="dox-ref-id" select="@refid"/>
<xsl:variable name="ref-name">
<xsl:call-template name="strip-beast-ns">
<xsl:with-param name="name"
select="(/doxygen//compounddef[@id=$dox-ref-id])[1]/compoundname"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="ref-id">
<xsl:call-template name="make-id">
<xsl:with-param name="name" select="$ref-name"/>
</xsl:call-template>
</xsl:variable>
<xsl:text>[link beast.ref.</xsl:text>
<xsl:value-of select="$ref-id"/>
<xsl:text> `</xsl:text>
<xsl:value-of name="text" select="$ref-name"/>
<xsl:text>`]</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>`</xsl:text>
<xsl:value-of select="."/>
<xsl:text>`</xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:text>[role red |3|</xsl:text>
<xsl:value-of select="."/>
<xsl:text>]</xsl:text>
</xsl:template>
<xsl:template match="ref[@kindref='member']" mode="markup">
<xsl:variable name="dox-ref-id" select="@refid"/>
<xsl:variable name="memberdefs" select="/doxygen//compounddef/sectiondef/memberdef[@id=$dox-ref-id]"/>
<xsl:choose>
<xsl:when test="contains(@refid, 'namespaceboost_1_1asio') and count($memberdefs) &gt; 0">
<xsl:variable name="dox-compound-name" select="($memberdefs)[1]/../../compoundname"/>
<xsl:variable name="dox-name" select="($memberdefs)[1]/name"/>
<xsl:variable name="ref-name">
<xsl:call-template name="strip-beast-ns">
<xsl:with-param name="name" select="concat($dox-compound-name,'::',$dox-name)"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="ref-id">
<xsl:call-template name="make-id">
<xsl:with-param name="name" select="$ref-name"/>
</xsl:call-template>
</xsl:variable>
<xsl:text>[link beast.ref.</xsl:text>
<xsl:value-of select="$ref-id"/>
<xsl:text> `</xsl:text>
<xsl:value-of name="text" select="$ref-name"/>
<xsl:text>`]</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>`</xsl:text>
<xsl:value-of select="."/>
<xsl:text>`</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="ref[@kindref='member']" mode="markup-nested">
<xsl:variable name="name">
<xsl:value-of select="."/>
</xsl:variable>
<xsl:variable name="dox-ref-id" select="@refid"/>
<xsl:variable name="memberdefs" select="/doxygen//compounddef/sectiondef/memberdef[@id=$dox-ref-id]"/>
<xsl:variable name="def-kind" select="($memberdefs)/../../@kind"/>
<xsl:variable name="sec-kind" select="($memberdefs)/../@kind"/>
<xsl:choose>
<xsl:when test="contains(@refid, 'namespaceboost_1_1asio') and count($memberdefs) &gt; 0">
<xsl:when test="contains(@refid, 'beast') and count($memberdefs) &gt; 0">
<xsl:variable name="dox-compound-name" select="($memberdefs)[1]/../../compoundname"/>
<xsl:variable name="dox-name" select="($memberdefs)[1]/name"/>
<xsl:variable name="ref-name">
<xsl:call-template name="strip-beast-ns">
<xsl:with-param name="name" select="concat($dox-compound-name,'::',$dox-name)"/>
<xsl:with-param name="name" select="$dox-compound-name"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="ref-id">
@@ -651,16 +717,49 @@
<xsl:with-param name="name" select="$ref-name"/>
</xsl:call-template>
</xsl:variable>
<xsl:text>[link beast.ref.</xsl:text>
<!--<xsl:text>|2|</xsl:text>-->
<!--
<xsl:text>[role red def-kind='</xsl:text>
<xsl:value-of select="$def-kind"/>
<xsl:text>', sec-kind='</xsl:text>
<xsl:value-of select="$sec-kind"/>
<xsl:text>', ref-id='</xsl:text>
<xsl:value-of select="$ref-id"/>
<xsl:text> `</xsl:text>
<xsl:value-of name="text" select="$ref-name"/>
<xsl:text>`]</xsl:text>
<xsl:text>'] </xsl:text>
-->
<xsl:choose>
<xsl:when test="$def-kind = 'namespace'">
<xsl:text>[link beast.ref.</xsl:text>
<xsl:choose>
<xsl:when test="string-length($ref-id) &gt; 0">
<xsl:value-of select="concat($ref-id,'__',$dox-name)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$dox-name"/>
</xsl:otherwise>
</xsl:choose>
<xsl:text> `</xsl:text>
<xsl:value-of name="text" select="$dox-name"/>
<xsl:text>`]</xsl:text>
</xsl:when>
<xsl:when test="$def-kind = 'class' or $def-kind = 'struct'">
<xsl:text>[link beast.ref.</xsl:text>
<xsl:value-of select="concat($ref-id,'.',$dox-name)"/>
<xsl:text> `</xsl:text>
<xsl:value-of name="text" select="$name"/>
<xsl:text>`]</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>[role red </xsl:text>
<xsl:value-of select="$name"/>
<xsl:text>]</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:text>`</xsl:text>
<xsl:value-of select="."/>
<xsl:text>`</xsl:text>
<xsl:text>[role red </xsl:text>
<xsl:value-of select="$name"/>
<xsl:text>]</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
@@ -1185,7 +1284,8 @@
</xsl:call-template>
</xsl:variable>
<xsl:if test="string-length($stripped-type) &gt; 0">
<xsl:value-of select="$stripped-type"/><xsl:text> </xsl:text>
<xsl:value-of select="$stripped-type"/>
<xsl:text>&#xd;</xsl:text>
</xsl:if>
<xsl:text>``[link beast.ref.</xsl:text>
<xsl:value-of select="$class-id"/>
@@ -1412,21 +1512,62 @@
</xsl:template>
<xsl:template match="templateparamlist" mode="class-detail">
<xsl:text>template&lt;&#xd;</xsl:text>
<xsl:apply-templates select="param" mode="class-detail-template"/>
<xsl:text>&gt;&#xd;</xsl:text>
</xsl:template>
<xsl:template match="param" mode="class-detail-template">
<xsl:text> </xsl:text>
<xsl:choose>
<xsl:when test="type = 'class AsyncStream'">
<xsl:text>class ``[link beast.types.stream.AsyncStream [*AsyncStream]]``</xsl:text>
</xsl:when>
<xsl:when test="type = 'class AsyncReadStream'">
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/AsyncReadStream.html [*AsyncReadStream]]``</xsl:text>
</xsl:when>
<xsl:when test="type = 'class AsyncWriteStream'">
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/AsyncWriteStream.html [*AsyncWriteStream]]``</xsl:text>
</xsl:when>
<xsl:when test="type = 'class Body'">
<xsl:text>class ``[link beast.types.Body [*Body]]``</xsl:text>
</xsl:when>
<xsl:when test="type = 'class Streambuf'">
<xsl:when test="type = 'class BufferSequence'">
<xsl:text>class ``[link beast.types.BufferSequence [*BufferSequence]]``</xsl:text>
</xsl:when>
<xsl:when test="(type = 'class' or type = 'class...') and declname = 'BufferSequence'">
<xsl:value-of select="type"/>
<xsl:text> ``[link beast.types.BufferSequence [*BufferSequence]]``</xsl:text>
</xsl:when>
<xsl:when test="declname = 'CompletionHandler' or type = 'class CompletionHandler'">
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/CompletionHandler.html [*CompletionHandler]]``</xsl:text>
</xsl:when>
<xsl:when test="declname = 'ConstBufferSequence' or type = 'class ConstBufferSequence'">
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/ConstBufferSequence.html [*ConstBufferSequence]]``</xsl:text>
</xsl:when>
<xsl:when test="declname = 'MutableBufferSequence' or type = 'class MutableBufferSequence'">
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/MutableBufferSequence.html [*MutableBufferSequence]]``</xsl:text>
</xsl:when>
<xsl:when test="declname = 'Stream' or type = 'class Stream'">
<xsl:text>class ``[link beast.types.stream.Stream [*Stream]]``</xsl:text>
</xsl:when>
<xsl:when test="declname = 'Streambuf' or type = 'class Streambuf'">
<xsl:text>class ``[link beast.types.Streambuf [*Streambuf]]``</xsl:text>
</xsl:when>
<xsl:when test="type = 'class SyncStream'">
<xsl:text>class ``[link beast.types.stream.SyncStream [*SyncStream]]``</xsl:text>
</xsl:when>
<xsl:when test="declname = 'SyncReadStream' or type = 'class SyncReadStream'">
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/SyncReadStream.html [*SyncReadStream]]``</xsl:text>
</xsl:when>
<xsl:when test="declname = 'SyncWriteStream' or type = 'class SyncWriteStream'">
<xsl:text>class ``[@http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/reference/SyncWriteStream.html [*SyncWriteStream]]``</xsl:text>
</xsl:when>
<xsl:when test="declname = 'T'">
<xsl:value-of select="declname"/>
</xsl:when>
@@ -1466,28 +1607,19 @@
<xsl:value-of select="array"/>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="' &amp;&amp;' = substring(type, string-length(type) - 2)">
<xsl:value-of select="substring(type, 1, string-length(type) - 3)"/>
<xsl:text>&amp;&amp;</xsl:text>
</xsl:when>
<xsl:when test="' &amp;' = substring(type, string-length(type) - 1)">
<xsl:value-of select="substring(type, 1, string-length(type) - 2)"/>
<xsl:text>&amp;</xsl:text>
</xsl:when>
<xsl:when test="' *' = substring(type, string-length(type) - 1)">
<xsl:value-of select="substring(type, 1, string-length(type) - 2)"/>
<xsl:text>*</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="type"/>
</xsl:otherwise>
</xsl:choose>
<xsl:text> </xsl:text>
<xsl:value-of select="declname"/>
<xsl:call-template name="cleanup-param">
<xsl:with-param name="name" select="type"/>
</xsl:call-template>
<xsl:if test="count(declname) > 0">
<xsl:text> </xsl:text>
<xsl:value-of select="declname"/>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="count(defval) > 0"> = <xsl:value-of select="defval"/></xsl:if>
<xsl:if test="count(defval) > 0">
<xsl:text> = </xsl:text>
<xsl:value-of select="defval"/>
</xsl:if>
<xsl:if test="not(position() = last())">
<xsl:text>,</xsl:text>
</xsl:if>