include/boost/burl/message_writer.hpp
100.0% Lines (30/30)
84.4% List of functions (38/45)
75.0% Branches (6/8)
Functions (45)
Function
Calls
Lines
Branches
Blocks
boost::burl::message_writer<boost::burl::detail::pooled_connection>::message_writer(boost::burl::detail::pooled_connection*, boost::burl::serializer*)
:84
35x
100.0%
50.0%
60.0%
boost::burl::message_writer<boost::burl::message_writer_test::flaky_write_stream>::message_writer(boost::burl::message_writer_test::flaky_write_stream*, boost::burl::serializer*)
:84
2x
100.0%
50.0%
60.0%
boost::burl::message_writer<boost::capy::test::stream>::message_writer(boost::capy::test::stream*, boost::burl::serializer*)
:84
8x
100.0%
50.0%
60.0%
boost::burl::message_writer<boost::capy::test::write_stream>::message_writer(boost::capy::test::write_stream*, boost::burl::serializer*)
:84
12x
100.0%
50.0%
60.0%
boost::burl::message_writer<boost::burl::detail::pooled_connection>::prepare(std::span<boost::capy::mutable_buffer, 18446744073709551615ul>)
:99
0
0.0%
–
0.0%
boost::burl::message_writer<boost::capy::test::write_stream>::prepare(std::span<boost::capy::mutable_buffer, 18446744073709551615ul>)
:99
3x
100.0%
–
100.0%
boost::burl::message_writer<boost::burl::detail::pooled_connection>::commit(unsigned long)
:115
0
0.0%
–
0.0%
boost::burl::message_writer<boost::capy::test::write_stream>::commit(unsigned long)
:115
2x
100.0%
–
100.0%
boost::burl::message_writer<boost::burl::detail::pooled_connection>::commit_eof(unsigned long)
:127
0
0.0%
–
0.0%
boost::burl::message_writer<boost::capy::test::write_stream>::commit_eof(unsigned long)
:127
1x
100.0%
–
100.0%
boost::burl::message_writer<boost::burl::detail::pooled_connection>::write_eof()
:137
33x
100.0%
–
100.0%
boost::burl::message_writer<boost::burl::message_writer_test::flaky_write_stream>::write_eof()
:137
1x
100.0%
–
100.0%
boost::burl::message_writer<boost::capy::test::stream>::write_eof()
:137
4x
100.0%
–
100.0%
boost::burl::message_writer<boost::capy::test::write_stream>::write_eof()
:137
4x
100.0%
–
100.0%
boost::burl::message_writer<boost::capy::test::write_stream>::write_header()
:161
2x
100.0%
–
100.0%
boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::burl::message_writer<boost::burl::detail::pooled_connection>::write_some<std::span<boost::capy::const_buffer const, 18446744073709551615ul> >(std::span<boost::capy::const_buffer const, 18446744073709551615ul>)
:180
0
0.0%
–
0.0%
boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::burl::message_writer<boost::capy::test::write_stream>::write_some<boost::capy::const_buffer>(boost::capy::const_buffer)
:180
1x
100.0%
–
100.0%
boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::burl::message_writer<boost::capy::test::write_stream>::write_some<std::span<boost::capy::const_buffer const, 18446744073709551615ul> >(std::span<boost::capy::const_buffer const, 18446744073709551615ul>)
:180
1x
100.0%
–
100.0%
boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::burl::message_writer<boost::burl::detail::pooled_connection>::write<std::span<boost::capy::const_buffer const, 18446744073709551615ul> >(std::span<boost::capy::const_buffer const, 18446744073709551615ul>)
:197
0
0.0%
–
0.0%
boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::burl::message_writer<boost::burl::message_writer_test::flaky_write_stream>::write<boost::capy::const_buffer>(boost::capy::const_buffer)
:197
2x
100.0%
–
100.0%
boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::burl::message_writer<boost::capy::test::stream>::write<boost::capy::const_buffer>(boost::capy::const_buffer)
:197
8x
100.0%
–
100.0%
boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::burl::message_writer<boost::capy::test::write_stream>::write<boost::capy::const_buffer>(boost::capy::const_buffer)
:197
2x
100.0%
–
100.0%
boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::burl::message_writer<boost::capy::test::write_stream>::write<std::span<boost::capy::const_buffer const, 18446744073709551615ul> >(std::span<boost::capy::const_buffer const, 18446744073709551615ul>)
:197
1x
100.0%
–
100.0%
boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::burl::message_writer<boost::burl::detail::pooled_connection>::write_eof<std::span<boost::capy::const_buffer const, 18446744073709551615ul> >(std::span<boost::capy::const_buffer const, 18446744073709551615ul>)
:217
2x
100.0%
–
100.0%
boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::burl::message_writer<boost::burl::message_writer_test::flaky_write_stream>::write_eof<boost::capy::const_buffer>(boost::capy::const_buffer)
:217
17x
100.0%
–
100.0%
boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::burl::message_writer<boost::capy::test::write_stream>::write_eof<boost::capy::const_buffer>(boost::capy::const_buffer)
:217
3x
100.0%
–
100.0%
boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::burl::message_writer<boost::capy::test::write_stream>::write_eof<std::array<boost::capy::const_buffer, 24ul> >(std::array<boost::capy::const_buffer, 24ul>)
:217
2x
100.0%
–
100.0%
boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::burl::message_writer<boost::capy::test::write_stream>::write_eof<std::array<boost::capy::const_buffer, 2ul> >(std::array<boost::capy::const_buffer, 2ul>)
:217
1x
100.0%
–
100.0%
boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::burl::message_writer<boost::capy::test::write_stream>::write_eof<std::span<boost::capy::const_buffer const, 18446744073709551615ul> >(std::span<boost::capy::const_buffer const, 18446744073709551615ul>)
:217
1x
100.0%
–
100.0%
boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::burl::message_writer<boost::burl::detail::pooled_connection>::drive_<boost::capy::const_buffer>(boost::burl::detail::pooled_connection&, boost::burl::serializer&, boost::capy::const_buffer, bool)
:252
33x
100.0%
100.0%
44.0%
boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::burl::message_writer<boost::burl::detail::pooled_connection>::drive_<std::span<boost::capy::const_buffer const, 18446744073709551615ul> >(boost::burl::detail::pooled_connection&, boost::burl::serializer&, std::span<boost::capy::const_buffer const, 18446744073709551615ul>, bool)
:252
2x
100.0%
100.0%
44.0%
boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::burl::message_writer<boost::burl::message_writer_test::flaky_write_stream>::drive_<boost::capy::const_buffer>(boost::burl::message_writer_test::flaky_write_stream&, boost::burl::serializer&, boost::capy::const_buffer, bool)
:252
20x
100.0%
100.0%
44.0%
boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::burl::message_writer<boost::capy::test::stream>::drive_<boost::capy::const_buffer>(boost::capy::test::stream&, boost::burl::serializer&, boost::capy::const_buffer, bool)
:252
12x
100.0%
100.0%
44.0%
boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::burl::message_writer<boost::capy::test::write_stream>::drive_<boost::capy::const_buffer>(boost::capy::test::write_stream&, boost::burl::serializer&, boost::capy::const_buffer, bool)
:252
14x
100.0%
100.0%
44.0%
boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::burl::message_writer<boost::capy::test::write_stream>::drive_<std::array<boost::capy::const_buffer, 24ul> >(boost::capy::test::write_stream&, boost::burl::serializer&, std::array<boost::capy::const_buffer, 24ul>, bool)
:252
2x
100.0%
100.0%
44.0%
boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::burl::message_writer<boost::capy::test::write_stream>::drive_<std::array<boost::capy::const_buffer, 2ul> >(boost::capy::test::write_stream&, boost::burl::serializer&, std::array<boost::capy::const_buffer, 2ul>, bool)
:252
1x
100.0%
100.0%
44.0%
boost::capy::task<std::tuple<std::error_code, unsigned long> > boost::burl::message_writer<boost::capy::test::write_stream>::drive_<std::span<boost::capy::const_buffer const, 18446744073709551615ul> >(boost::capy::test::write_stream&, boost::burl::serializer&, std::span<boost::capy::const_buffer const, 18446744073709551615ul>, bool)
:252
3x
100.0%
100.0%
44.0%
boost::burl::message_writer<boost::burl::detail::pooled_connection>::drain_(boost::burl::detail::pooled_connection&, boost::burl::serializer&)
:278
0
0.0%
0.0%
0.0%
boost::burl::message_writer<boost::capy::test::write_stream>::drain_(boost::capy::test::write_stream&, boost::burl::serializer&)
:278
3x
100.0%
100.0%
44.0%
boost::burl::message_writer<boost::burl::detail::pooled_connection>::commit_(boost::burl::detail::pooled_connection&, boost::burl::serializer&, unsigned long)
:289
0
0.0%
0.0%
0.0%
boost::burl::message_writer<boost::capy::test::write_stream>::commit_(boost::capy::test::write_stream&, boost::burl::serializer&, unsigned long)
:289
2x
100.0%
100.0%
44.0%
boost::burl::message_writer<boost::burl::detail::pooled_connection>::commit_eof_(boost::burl::detail::pooled_connection&, boost::burl::serializer&, unsigned long)
:303
33x
100.0%
100.0%
44.0%
boost::burl::message_writer<boost::burl::message_writer_test::flaky_write_stream>::commit_eof_(boost::burl::message_writer_test::flaky_write_stream&, boost::burl::serializer&, unsigned long)
:303
1x
100.0%
100.0%
44.0%
boost::burl::message_writer<boost::capy::test::stream>::commit_eof_(boost::capy::test::stream&, boost::burl::serializer&, unsigned long)
:303
4x
100.0%
100.0%
44.0%
boost::burl::message_writer<boost::capy::test::write_stream>::commit_eof_(boost::capy::test::write_stream&, boost::burl::serializer&, unsigned long)
:303
5x
100.0%
100.0%
44.0%
| Line | Branch | TLA | Hits | Source Code |
|---|---|---|---|---|
| 1 | // | |||
| 2 | // Copyright (c) 2026 Mohammad Nejati | |||
| 3 | // | |||
| 4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | |||
| 5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |||
| 6 | // | |||
| 7 | // Official repository: https://github.com/cppalliance/burl | |||
| 8 | // | |||
| 9 | ||||
| 10 | #ifndef BOOST_BURL_MESSAGE_WRITER_HPP | |||
| 11 | #define BOOST_BURL_MESSAGE_WRITER_HPP | |||
| 12 | ||||
| 13 | #include <boost/burl/serializer.hpp> | |||
| 14 | ||||
| 15 | #include <boost/assert.hpp> | |||
| 16 | #include <boost/capy/buffers/consuming_buffers.hpp> | |||
| 17 | #include <boost/capy/concept/write_stream.hpp> | |||
| 18 | #include <boost/capy/io_task.hpp> | |||
| 19 | ||||
| 20 | #include <cstddef> | |||
| 21 | #include <span> | |||
| 22 | #include <utility> | |||
| 23 | ||||
| 24 | namespace boost | |||
| 25 | { | |||
| 26 | namespace burl | |||
| 27 | { | |||
| 28 | ||||
| 29 | /** Drives a @ref serializer over a stream. | |||
| 30 | ||||
| 31 | A writer binds a stream to a serializer. It | |||
| 32 | holds only pointers to both, which must outlive | |||
| 33 | it. | |||
| 34 | ||||
| 35 | @par Example | |||
| 36 | @code | |||
| 37 | serializer sr( cfg ); | |||
| 38 | message_writer writer( &sock, &sr ); | |||
| 39 | ||||
| 40 | sr.start( &head ); | |||
| 41 | ||||
| 42 | auto [ec, n] = co_await writer.write_eof( | |||
| 43 | capy::make_buffer( body )); | |||
| 44 | @endcode | |||
| 45 | ||||
| 46 | Every operation writes the header first if it | |||
| 47 | has not gone out yet. Small writes coalesce in | |||
| 48 | the serializer's staging buffer; large ones are | |||
| 49 | spliced into the same gathered write as the | |||
| 50 | framing, without copying. | |||
| 51 | ||||
| 52 | If an operation is cancelled mid-write, the | |||
| 53 | serializer's accounting stays true to the wire: | |||
| 54 | the completion counts already reported cover | |||
| 55 | exactly the consumed octets, and re-issuing a | |||
| 56 | write of the unconsumed remainder resumes the | |||
| 57 | message. | |||
| 58 | ||||
| 59 | This type satisfies @ref capy::WriteStream, | |||
| 60 | @ref http::WriteSink, and @ref http::BufferSink, | |||
| 61 | all over the octets of the message body. | |||
| 62 | ||||
| 63 | @tparam S A type satisfying @ref capy::WriteStream. | |||
| 64 | ||||
| 65 | @see @ref serializer. | |||
| 66 | */ | |||
| 67 | template<capy::WriteStream S> | |||
| 68 | class message_writer | |||
| 69 | { | |||
| 70 | S* s_; | |||
| 71 | serializer* sr_; | |||
| 72 | ||||
| 73 | public: | |||
| 74 | /** Constructor. | |||
| 75 | ||||
| 76 | @par Preconditions | |||
| 77 | Neither pointer is null, and both objects | |||
| 78 | outlive the writer. | |||
| 79 | ||||
| 80 | @param stream The stream to write to. | |||
| 81 | ||||
| 82 | @param sr The serializer to drive. | |||
| 83 | */ | |||
| 84 | 57x | message_writer(S* stream, serializer* sr) noexcept | ||
| 85 | 57x | : s_(stream) | ||
| 86 | 57x | , sr_(sr) | ||
| 87 | { | |||
| 88 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
|
57x | BOOST_ASSERT(s_ != nullptr); | |
| 89 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
|
57x | BOOST_ASSERT(sr_ != nullptr); | |
| 90 | 57x | } | ||
| 91 | ||||
| 92 | /** Return writable staging memory. | |||
| 93 | ||||
| 94 | @param dest The descriptors to fill. | |||
| 95 | ||||
| 96 | @see @ref serializer::prepare. | |||
| 97 | */ | |||
| 98 | std::span<capy::mutable_buffer> | |||
| 99 | 3x | prepare(std::span<capy::mutable_buffer> dest) | ||
| 100 | { | |||
| 101 | 3x | return sr_->prepare(dest); | ||
| 102 | } | |||
| 103 | ||||
| 104 | /** Asynchronously commit staged octets. | |||
| 105 | ||||
| 106 | Reports octets written into memory obtained | |||
| 107 | from @ref prepare, flushing the staging | |||
| 108 | buffer when it runs low. | |||
| 109 | ||||
| 110 | @param n The number of octets written. | |||
| 111 | ||||
| 112 | @return An awaitable yielding `(error_code)`. | |||
| 113 | */ | |||
| 114 | capy::io_task<> | |||
| 115 | 2x | commit(std::size_t n) | ||
| 116 | { | |||
| 117 | 2x | return commit_(*s_, *sr_, n); | ||
| 118 | } | |||
| 119 | ||||
| 120 | /** Asynchronously commit final octets and end the body. | |||
| 121 | ||||
| 122 | @param n The number of octets written. | |||
| 123 | ||||
| 124 | @return An awaitable yielding `(error_code)`. | |||
| 125 | */ | |||
| 126 | capy::io_task<> | |||
| 127 | 1x | commit_eof(std::size_t n) | ||
| 128 | { | |||
| 129 | 1x | return commit_eof_(*s_, *sr_, n); | ||
| 130 | } | |||
| 131 | ||||
| 132 | /** Asynchronously end the body with no more octets. | |||
| 133 | ||||
| 134 | @return An awaitable yielding `(error_code)`. | |||
| 135 | */ | |||
| 136 | capy::io_task<> | |||
| 137 | 42x | write_eof() | ||
| 138 | { | |||
| 139 | 42x | return commit_eof_(*s_, *sr_, 0); | ||
| 140 | } | |||
| 141 | ||||
| 142 | /** Asynchronously write the message header. | |||
| 143 | ||||
| 144 | Flushes pending output without ending the | |||
| 145 | body. This sends the header, if needed, and | |||
| 146 | any staged data after it. | |||
| 147 | ||||
| 148 | Mainly used for `Expect: 100-continue`, | |||
| 149 | where the server must receive the header | |||
| 150 | before the body is generated. | |||
| 151 | ||||
| 152 | Once the header is sent, the framing and | |||
| 153 | encoding are fixed. Small bodies can no | |||
| 154 | longer switch to `Content-Length` or | |||
| 155 | identity encoding. | |||
| 156 | ||||
| 157 | @return An awaitable yielding | |||
| 158 | `(error_code)`. | |||
| 159 | */ | |||
| 160 | capy::io_task<> | |||
| 161 | 2x | write_header() | ||
| 162 | { | |||
| 163 | 2x | return drain_(*s_, *sr_); | ||
| 164 | } | |||
| 165 | ||||
| 166 | /** Asynchronously write body octets. | |||
| 167 | ||||
| 168 | Writes at least one octet of `buffers` | |||
| 169 | unless it is empty; small inputs coalesce | |||
| 170 | without I/O. May consume the input only | |||
| 171 | partially. | |||
| 172 | ||||
| 173 | @param buffers The octets to write. | |||
| 174 | ||||
| 175 | @return An awaitable yielding | |||
| 176 | `(error_code,std::size_t)`. | |||
| 177 | */ | |||
| 178 | template<capy::ConstBufferSequence CB> | |||
| 179 | capy::io_task<std::size_t> | |||
| 180 | 2x | write_some(CB buffers) | ||
| 181 | { | |||
| 182 | 2x | return drive_(*s_, *sr_, std::move(buffers), true); | ||
| 183 | } | |||
| 184 | ||||
| 185 | /** Asynchronously write a whole buffer sequence. | |||
| 186 | ||||
| 187 | Writes until `buffers` is fully consumed or | |||
| 188 | an error occurs. | |||
| 189 | ||||
| 190 | @param buffers The octets to write. | |||
| 191 | ||||
| 192 | @return An awaitable yielding | |||
| 193 | `(error_code,std::size_t)`. | |||
| 194 | */ | |||
| 195 | template<capy::ConstBufferSequence CB> | |||
| 196 | capy::io_task<std::size_t> | |||
| 197 | 13x | write(CB buffers) | ||
| 198 | { | |||
| 199 | 13x | return drive_(*s_, *sr_, std::move(buffers), true); | ||
| 200 | } | |||
| 201 | ||||
| 202 | /** Asynchronously write final octets and end the body. | |||
| 203 | ||||
| 204 | Writes all of `buffers` and completes the | |||
| 205 | message. The whole body is supplied up | |||
| 206 | front, which is what lets a small body of | |||
| 207 | undeclared size go out with | |||
| 208 | `Content-Length` framing. | |||
| 209 | ||||
| 210 | @param buffers The final octets to write. | |||
| 211 | ||||
| 212 | @return An awaitable yielding | |||
| 213 | `(error_code,std::size_t)`. | |||
| 214 | */ | |||
| 215 | template<capy::ConstBufferSequence CB> | |||
| 216 | capy::io_task<std::size_t> | |||
| 217 | 26x | write_eof(CB buffers) | ||
| 218 | { | |||
| 219 | 26x | return drive_(*s_, *sr_, std::move(buffers), false); | ||
| 220 | } | |||
| 221 | ||||
| 222 | private: | |||
| 223 | template<capy::ConstBufferSequence CB> | |||
| 224 | static capy::io_task<std::size_t> | |||
| 225 | drive_( | |||
| 226 | S& stream, | |||
| 227 | serializer& sr, | |||
| 228 | CB buffers, | |||
| 229 | bool more); | |||
| 230 | ||||
| 231 | static capy::io_task<> | |||
| 232 | drain_(S& stream, serializer& sr); | |||
| 233 | ||||
| 234 | static capy::io_task<> | |||
| 235 | commit_( | |||
| 236 | S& stream, | |||
| 237 | serializer& sr, | |||
| 238 | std::size_t n); | |||
| 239 | ||||
| 240 | static capy::io_task<> | |||
| 241 | commit_eof_( | |||
| 242 | S& stream, | |||
| 243 | serializer& sr, | |||
| 244 | std::size_t n); | |||
| 245 | }; | |||
| 246 | ||||
| 247 | //------------------------------------------------ | |||
| 248 | ||||
| 249 | template<capy::WriteStream S> | |||
| 250 | template<capy::ConstBufferSequence CB> | |||
| 251 | capy::io_task<std::size_t> | |||
| 252 |
1/1✓ Branch 1 taken 87 times.
|
87x | message_writer<S>:: | |
| 253 | drive_( | |||
| 254 | S& stream, | |||
| 255 | serializer& sr, | |||
| 256 | CB buffers, | |||
| 257 | bool more) | |||
| 258 | { | |||
| 259 | capy::consuming_buffers cb(buffers); | |||
| 260 | capy::const_buffer dest[16]; | |||
| 261 | std::size_t total = 0; | |||
| 262 | for(;;) | |||
| 263 | { | |||
| 264 | auto const fr = sr.frame(dest, cb.data(), more); | |||
| 265 | if(fr.has_error()) | |||
| 266 | co_return { fr.error(), total }; | |||
| 267 | auto [ec, n] = co_await stream.write_some(*fr); | |||
| 268 | auto const k = sr.consume(n); | |||
| 269 | cb.consume(k); | |||
| 270 | total += k; | |||
| 271 | if(ec || n == 0) | |||
| 272 | co_return { ec, total }; | |||
| 273 | } | |||
| 274 | 174x | } | ||
| 275 | ||||
| 276 | template<capy::WriteStream S> | |||
| 277 | capy::io_task<> | |||
| 278 |
1/1✓ Branch 1 taken 3 times.
|
3x | message_writer<S>:: | |
| 279 | drain_(S& stream, serializer& sr) | |||
| 280 | { | |||
| 281 | auto [ec, n] = co_await drive_( | |||
| 282 | stream, sr, capy::const_buffer{}, true); | |||
| 283 | (void)n; | |||
| 284 | co_return { ec }; | |||
| 285 | 6x | } | ||
| 286 | ||||
| 287 | template<capy::WriteStream S> | |||
| 288 | capy::io_task<> | |||
| 289 |
1/1✓ Branch 1 taken 2 times.
|
2x | message_writer<S>:: | |
| 290 | commit_( | |||
| 291 | S& stream, | |||
| 292 | serializer& sr, | |||
| 293 | std::size_t n) | |||
| 294 | { | |||
| 295 | sr.commit(n); | |||
| 296 | if(!sr.should_drain()) | |||
| 297 | co_return {}; | |||
| 298 | co_return co_await drain_(stream, sr); | |||
| 299 | 4x | } | ||
| 300 | ||||
| 301 | template<capy::WriteStream S> | |||
| 302 | capy::io_task<> | |||
| 303 |
1/1✓ Branch 1 taken 43 times.
|
43x | message_writer<S>:: | |
| 304 | commit_eof_( | |||
| 305 | S& stream, | |||
| 306 | serializer& sr, | |||
| 307 | std::size_t n) | |||
| 308 | { | |||
| 309 | sr.commit(n); | |||
| 310 | auto [ec, k] = co_await drive_( | |||
| 311 | stream, sr, capy::const_buffer{}, false); | |||
| 312 | (void)k; | |||
| 313 | co_return { ec }; | |||
| 314 | 86x | } | ||
| 315 | ||||
| 316 | } // namespace burl | |||
| 317 | } // namespace boost | |||
| 318 | ||||
| 319 | #endif | |||
| 320 |