5
// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
7
// Distributed under the Boost Software License, Version 1.0. (See accompanying
8
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
11
#ifndef ASIO_BUFFER_HPP
12
#define ASIO_BUFFER_HPP
14
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
16
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18
#include "asio/detail/push_options.hpp"
20
#include "asio/detail/push_options.hpp"
22
#include <boost/config.hpp>
23
#include <boost/array.hpp>
24
#include <boost/type_traits/is_const.hpp>
27
#include "asio/detail/pop_options.hpp"
29
#if defined(BOOST_MSVC)
30
# if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0)
31
# if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
32
# define ASIO_ENABLE_BUFFER_DEBUGGING
33
# endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
34
# endif // defined(_HAS_ITERATOR_DEBUGGING)
35
#endif // defined(BOOST_MSVC)
38
# if defined(_GLIBCXX_DEBUG)
39
# if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
40
# define ASIO_ENABLE_BUFFER_DEBUGGING
41
# endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
42
# endif // defined(_GLIBCXX_DEBUG)
43
#endif // defined(__GNUC__)
45
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
46
# include "asio/detail/push_options.hpp"
47
# include <boost/function.hpp>
48
# include "asio/detail/pop_options.hpp"
49
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
57
void* buffer_cast_helper(const mutable_buffer&);
58
const void* buffer_cast_helper(const const_buffer&);
59
std::size_t buffer_size_helper(const mutable_buffer&);
60
std::size_t buffer_size_helper(const const_buffer&);
63
/// Holds a buffer that can be modified.
65
* The mutable_buffer class provides a safe representation of a buffer that can
66
* be modified. It does not own the underlying data, and so is cheap to copy or
72
/// Construct an empty buffer.
79
/// Construct a buffer to represent a given memory range.
80
mutable_buffer(void* data, std::size_t size)
86
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
87
mutable_buffer(void* data, std::size_t size,
88
boost::function<void()> debug_check)
91
debug_check_(debug_check)
95
const boost::function<void()>& get_debug_check() const
99
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
102
friend void* asio::detail::buffer_cast_helper(
103
const mutable_buffer& b);
104
friend std::size_t asio::detail::buffer_size_helper(
105
const mutable_buffer& b);
110
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
111
boost::function<void()> debug_check_;
112
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
117
inline void* buffer_cast_helper(const mutable_buffer& b)
119
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
120
if (b.size_ && b.debug_check_)
122
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
126
inline std::size_t buffer_size_helper(const mutable_buffer& b)
131
} // namespace detail
133
/// Cast a non-modifiable buffer to a specified pointer to POD type.
135
* @relates mutable_buffer
137
template <typename PointerToPodType>
138
inline PointerToPodType buffer_cast(const mutable_buffer& b)
140
return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
143
/// Get the number of bytes in a non-modifiable buffer.
145
* @relates mutable_buffer
147
inline std::size_t buffer_size(const mutable_buffer& b)
149
return detail::buffer_size_helper(b);
152
/// Create a new modifiable buffer that is offset from the start of another.
154
* @relates mutable_buffer
156
inline mutable_buffer operator+(const mutable_buffer& b, std::size_t start)
158
if (start > buffer_size(b))
159
return mutable_buffer();
160
char* new_data = buffer_cast<char*>(b) + start;
161
std::size_t new_size = buffer_size(b) - start;
162
return mutable_buffer(new_data, new_size
163
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
164
, b.get_debug_check()
165
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
169
/// Create a new modifiable buffer that is offset from the start of another.
171
* @relates mutable_buffer
173
inline mutable_buffer operator+(std::size_t start, const mutable_buffer& b)
175
if (start > buffer_size(b))
176
return mutable_buffer();
177
char* new_data = buffer_cast<char*>(b) + start;
178
std::size_t new_size = buffer_size(b) - start;
179
return mutable_buffer(new_data, new_size
180
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
181
, b.get_debug_check()
182
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
186
/// Adapts a single modifiable buffer so that it meets the requirements of the
187
/// MutableBufferSequence concept.
188
class mutable_buffers_1
189
: public mutable_buffer
192
/// The type for each element in the list of buffers.
193
typedef mutable_buffer value_type;
195
/// A random-access iterator type that may be used to read elements.
196
typedef const mutable_buffer* const_iterator;
198
/// Construct to represent a given memory range.
199
mutable_buffers_1(void* data, std::size_t size)
200
: mutable_buffer(data, size)
204
/// Construct to represent a single modifiable buffer.
205
explicit mutable_buffers_1(const mutable_buffer& b)
210
/// Get a random-access iterator to the first element.
211
const_iterator begin() const
216
/// Get a random-access iterator for one past the last element.
217
const_iterator end() const
223
/// Holds a buffer that cannot be modified.
225
* The const_buffer class provides a safe representation of a buffer that cannot
226
* be modified. It does not own the underlying data, and so is cheap to copy or
232
/// Construct an empty buffer.
239
/// Construct a buffer to represent a given memory range.
240
const_buffer(const void* data, std::size_t size)
246
/// Construct a non-modifiable buffer from a modifiable one.
247
const_buffer(const mutable_buffer& b)
248
: data_(asio::detail::buffer_cast_helper(b)),
249
size_(asio::detail::buffer_size_helper(b))
250
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
251
, debug_check_(b.get_debug_check())
252
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
256
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
257
const_buffer(const void* data, std::size_t size,
258
boost::function<void()> debug_check)
261
debug_check_(debug_check)
265
const boost::function<void()>& get_debug_check() const
269
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
272
friend const void* asio::detail::buffer_cast_helper(
273
const const_buffer& b);
274
friend std::size_t asio::detail::buffer_size_helper(
275
const const_buffer& b);
280
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
281
boost::function<void()> debug_check_;
282
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
287
inline const void* buffer_cast_helper(const const_buffer& b)
289
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
290
if (b.size_ && b.debug_check_)
292
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
296
inline std::size_t buffer_size_helper(const const_buffer& b)
301
} // namespace detail
303
/// Cast a non-modifiable buffer to a specified pointer to POD type.
305
* @relates const_buffer
307
template <typename PointerToPodType>
308
inline PointerToPodType buffer_cast(const const_buffer& b)
310
return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
313
/// Get the number of bytes in a non-modifiable buffer.
315
* @relates const_buffer
317
inline std::size_t buffer_size(const const_buffer& b)
319
return detail::buffer_size_helper(b);
322
/// Create a new non-modifiable buffer that is offset from the start of another.
324
* @relates const_buffer
326
inline const_buffer operator+(const const_buffer& b, std::size_t start)
328
if (start > buffer_size(b))
329
return const_buffer();
330
const char* new_data = buffer_cast<const char*>(b) + start;
331
std::size_t new_size = buffer_size(b) - start;
332
return const_buffer(new_data, new_size
333
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
334
, b.get_debug_check()
335
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
339
/// Create a new non-modifiable buffer that is offset from the start of another.
341
* @relates const_buffer
343
inline const_buffer operator+(std::size_t start, const const_buffer& b)
345
if (start > buffer_size(b))
346
return const_buffer();
347
const char* new_data = buffer_cast<const char*>(b) + start;
348
std::size_t new_size = buffer_size(b) - start;
349
return const_buffer(new_data, new_size
350
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
351
, b.get_debug_check()
352
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
356
/// Adapts a single non-modifiable buffer so that it meets the requirements of
357
/// the ConstBufferSequence concept.
358
class const_buffers_1
359
: public const_buffer
362
/// The type for each element in the list of buffers.
363
typedef const_buffer value_type;
365
/// A random-access iterator type that may be used to read elements.
366
typedef const const_buffer* const_iterator;
368
/// Construct to represent a given memory range.
369
const_buffers_1(const void* data, std::size_t size)
370
: const_buffer(data, size)
374
/// Construct to represent a single non-modifiable buffer.
375
explicit const_buffers_1(const const_buffer& b)
380
/// Get a random-access iterator to the first element.
381
const_iterator begin() const
386
/// Get a random-access iterator for one past the last element.
387
const_iterator end() const
393
/// An implementation of both the ConstBufferSequence and MutableBufferSequence
394
/// concepts to represent a null buffer sequence.
398
/// The type for each element in the list of buffers.
399
typedef mutable_buffer value_type;
401
/// A random-access iterator type that may be used to read elements.
402
typedef const mutable_buffer* const_iterator;
404
/// Get a random-access iterator to the first element.
405
const_iterator begin() const
410
/// Get a random-access iterator for one past the last element.
411
const_iterator end() const
420
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
423
template <typename Iterator>
424
class buffer_debug_check
427
buffer_debug_check(Iterator iter)
432
~buffer_debug_check()
434
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
435
// MSVC's string iterator checking may crash in a std::string::iterator
436
// object's destructor when the iterator points to an already-destroyed
437
// std::string object, unless the iterator is cleared first.
439
#endif // BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
451
} // namespace detail
452
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
454
/** @defgroup buffer asio::buffer
456
* @brief The asio::buffer function is used to create a buffer object to
457
* represent raw memory, an array of POD elements, a vector of POD elements,
460
* A buffer object represents a contiguous region of memory as a 2-tuple
461
* consisting of a pointer and size in bytes. A tuple of the form <tt>{void*,
462
* size_t}</tt> specifies a mutable (modifiable) region of memory. Similarly, a
463
* tuple of the form <tt>{const void*, size_t}</tt> specifies a const
464
* (non-modifiable) region of memory. These two forms correspond to the classes
465
* mutable_buffer and const_buffer, respectively. To mirror C++'s conversion
466
* rules, a mutable_buffer is implicitly convertible to a const_buffer, and the
467
* opposite conversion is not permitted.
469
* The simplest use case involves reading or writing a single buffer of a
472
* @code sock.send(asio::buffer(data, size)); @endcode
474
* In the above example, the return value of asio::buffer meets the
475
* requirements of the ConstBufferSequence concept so that it may be directly
476
* passed to the socket's write function. A buffer created for modifiable
477
* memory also meets the requirements of the MutableBufferSequence concept.
479
* An individual buffer may be created from a builtin array, std::vector or
480
* boost::array of POD elements. This helps prevent buffer overruns by
481
* automatically determining the size of the buffer:
483
* @code char d1[128];
484
* size_t bytes_transferred = sock.receive(asio::buffer(d1));
486
* std::vector<char> d2(128);
487
* bytes_transferred = sock.receive(asio::buffer(d2));
489
* boost::array<char, 128> d3;
490
* bytes_transferred = sock.receive(asio::buffer(d3)); @endcode
492
* In all three cases above, the buffers created are exactly 128 bytes long.
493
* Note that a vector is @e never automatically resized when creating or using
494
* a buffer. The buffer size is determined using the vector's <tt>size()</tt>
495
* member function, and not its capacity.
497
* @par Accessing Buffer Contents
499
* The contents of a buffer may be accessed using the asio::buffer_size
500
* and asio::buffer_cast functions:
502
* @code asio::mutable_buffer b1 = ...;
503
* std::size_t s1 = asio::buffer_size(b1);
504
* unsigned char* p1 = asio::buffer_cast<unsigned char*>(b1);
506
* asio::const_buffer b2 = ...;
507
* std::size_t s2 = asio::buffer_size(b2);
508
* const void* p2 = asio::buffer_cast<const void*>(b2); @endcode
510
* The asio::buffer_cast function permits violations of type safety, so
511
* uses of it in application code should be carefully considered.
513
* @par Buffer Invalidation
515
* A buffer object does not have any ownership of the memory it refers to. It
516
* is the responsibility of the application to ensure the memory region remains
517
* valid until it is no longer required for an I/O operation. When the memory
518
* is no longer available, the buffer is said to have been invalidated.
520
* For the asio::buffer overloads that accept an argument of type
521
* std::vector, the buffer objects returned are invalidated by any vector
522
* operation that also invalidates all references, pointers and iterators
523
* referring to the elements in the sequence (C++ Std, 23.2.4)
525
* For the asio::buffer overloads that accept an argument of type
526
* std::string, the buffer objects returned are invalidated according to the
527
* rules defined for invalidation of references, pointers and iterators
528
* referring to elements of the sequence (C++ Std, 21.3).
530
* @par Buffer Arithmetic
532
* Buffer objects may be manipulated using simple arithmetic in a safe way
533
* which helps prevent buffer overruns. Consider an array initialised as
536
* @code boost::array<char, 6> a = { 'a', 'b', 'c', 'd', 'e' }; @endcode
538
* A buffer object @c b1 created using:
540
* @code b1 = asio::buffer(a); @endcode
542
* represents the entire array, <tt>{ 'a', 'b', 'c', 'd', 'e' }</tt>. An
543
* optional second argument to the asio::buffer function may be used to
544
* limit the size, in bytes, of the buffer:
546
* @code b2 = asio::buffer(a, 3); @endcode
548
* such that @c b2 represents the data <tt>{ 'a', 'b', 'c' }</tt>. Even if the
549
* size argument exceeds the actual size of the array, the size of the buffer
550
* object created will be limited to the array size.
552
* An offset may be applied to an existing buffer to create a new one:
554
* @code b3 = b1 + 2; @endcode
556
* where @c b3 will set to represent <tt>{ 'c', 'd', 'e' }</tt>. If the offset
557
* exceeds the size of the existing buffer, the newly created buffer will be
560
* Both an offset and size may be specified to create a buffer that corresponds
561
* to a specific range of bytes within an existing buffer:
563
* @code b4 = asio::buffer(b1 + 1, 3); @endcode
565
* so that @c b4 will refer to the bytes <tt>{ 'b', 'c', 'd' }</tt>.
567
* @par Buffers and Scatter-Gather I/O
569
* To read or write using multiple buffers (i.e. scatter-gather I/O), multiple
570
* buffer objects may be assigned into a container that supports the
571
* MutableBufferSequence (for read) or ConstBufferSequence (for write) concepts:
575
* std::vector<char> d2(128);
576
* boost::array<char, 128> d3;
578
* boost::array<mutable_buffer, 3> bufs1 = {
581
* asio::buffer(d3) };
582
* bytes_transferred = sock.receive(bufs1);
584
* std::vector<const_buffer> bufs2;
585
* bufs2.push_back(asio::buffer(d1));
586
* bufs2.push_back(asio::buffer(d2));
587
* bufs2.push_back(asio::buffer(d3));
588
* bytes_transferred = sock.send(bufs2); @endcode
592
/// Create a new modifiable buffer from an existing buffer.
594
* @returns <tt>mutable_buffers_1(b)</tt>.
596
inline mutable_buffers_1 buffer(const mutable_buffer& b)
598
return mutable_buffers_1(b);
601
/// Create a new modifiable buffer from an existing buffer.
603
* @returns A mutable_buffers_1 value equivalent to:
604
* @code mutable_buffers_1(
605
* buffer_cast<void*>(b),
606
* min(buffer_size(b), max_size_in_bytes)); @endcode
608
inline mutable_buffers_1 buffer(const mutable_buffer& b,
609
std::size_t max_size_in_bytes)
611
return mutable_buffers_1(
612
mutable_buffer(buffer_cast<void*>(b),
613
buffer_size(b) < max_size_in_bytes
614
? buffer_size(b) : max_size_in_bytes
615
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
616
, b.get_debug_check()
617
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
621
/// Create a new non-modifiable buffer from an existing buffer.
623
* @returns <tt>const_buffers_1(b)</tt>.
625
inline const_buffers_1 buffer(const const_buffer& b)
627
return const_buffers_1(b);
630
/// Create a new non-modifiable buffer from an existing buffer.
632
* @returns A const_buffers_1 value equivalent to:
633
* @code const_buffers_1(
634
* buffer_cast<const void*>(b),
635
* min(buffer_size(b), max_size_in_bytes)); @endcode
637
inline const_buffers_1 buffer(const const_buffer& b,
638
std::size_t max_size_in_bytes)
640
return const_buffers_1(
641
const_buffer(buffer_cast<const void*>(b),
642
buffer_size(b) < max_size_in_bytes
643
? buffer_size(b) : max_size_in_bytes
644
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
645
, b.get_debug_check()
646
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
650
/// Create a new modifiable buffer that represents the given memory range.
652
* @returns <tt>mutable_buffers_1(data, size_in_bytes)</tt>.
654
inline mutable_buffers_1 buffer(void* data, std::size_t size_in_bytes)
656
return mutable_buffers_1(mutable_buffer(data, size_in_bytes));
659
/// Create a new non-modifiable buffer that represents the given memory range.
661
* @returns <tt>const_buffers_1(data, size_in_bytes)</tt>.
663
inline const_buffers_1 buffer(const void* data,
664
std::size_t size_in_bytes)
666
return const_buffers_1(const_buffer(data, size_in_bytes));
669
/// Create a new modifiable buffer that represents the given POD array.
671
* @returns A mutable_buffers_1 value equivalent to:
672
* @code mutable_buffers_1(
673
* static_cast<void*>(data),
674
* N * sizeof(PodType)); @endcode
676
template <typename PodType, std::size_t N>
677
inline mutable_buffers_1 buffer(PodType (&data)[N])
679
return mutable_buffers_1(mutable_buffer(data, N * sizeof(PodType)));
682
/// Create a new modifiable buffer that represents the given POD array.
684
* @returns A mutable_buffers_1 value equivalent to:
685
* @code mutable_buffers_1(
686
* static_cast<void*>(data),
687
* min(N * sizeof(PodType), max_size_in_bytes)); @endcode
689
template <typename PodType, std::size_t N>
690
inline mutable_buffers_1 buffer(PodType (&data)[N],
691
std::size_t max_size_in_bytes)
693
return mutable_buffers_1(
695
N * sizeof(PodType) < max_size_in_bytes
696
? N * sizeof(PodType) : max_size_in_bytes));
699
/// Create a new non-modifiable buffer that represents the given POD array.
701
* @returns A const_buffers_1 value equivalent to:
702
* @code const_buffers_1(
703
* static_cast<const void*>(data),
704
* N * sizeof(PodType)); @endcode
706
template <typename PodType, std::size_t N>
707
inline const_buffers_1 buffer(const PodType (&data)[N])
709
return const_buffers_1(const_buffer(data, N * sizeof(PodType)));
712
/// Create a new non-modifiable buffer that represents the given POD array.
714
* @returns A const_buffers_1 value equivalent to:
715
* @code const_buffers_1(
716
* static_cast<const void*>(data),
717
* min(N * sizeof(PodType), max_size_in_bytes)); @endcode
719
template <typename PodType, std::size_t N>
720
inline const_buffers_1 buffer(const PodType (&data)[N],
721
std::size_t max_size_in_bytes)
723
return const_buffers_1(
725
N * sizeof(PodType) < max_size_in_bytes
726
? N * sizeof(PodType) : max_size_in_bytes));
729
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) \
730
|| BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
732
// Borland C++ and Sun Studio think the overloads:
734
// unspecified buffer(boost::array<PodType, N>& array ...);
738
// unspecified buffer(boost::array<const PodType, N>& array ...);
740
// are ambiguous. This will be worked around by using a buffer_types traits
741
// class that contains typedefs for the appropriate buffer and container
742
// classes, based on whether PodType is const or non-const.
746
template <bool IsConst>
747
struct buffer_types_base;
750
struct buffer_types_base<false>
752
typedef mutable_buffer buffer_type;
753
typedef mutable_buffers_1 container_type;
757
struct buffer_types_base<true>
759
typedef const_buffer buffer_type;
760
typedef const_buffers_1 container_type;
763
template <typename PodType>
765
: public buffer_types_base<boost::is_const<PodType>::value>
769
} // namespace detail
771
template <typename PodType, std::size_t N>
772
inline typename detail::buffer_types<PodType>::container_type
773
buffer(boost::array<PodType, N>& data)
775
typedef typename asio::detail::buffer_types<PodType>::buffer_type
777
typedef typename asio::detail::buffer_types<PodType>::container_type
779
return container_type(
780
buffer_type(data.c_array(), data.size() * sizeof(PodType)));
783
template <typename PodType, std::size_t N>
784
inline typename detail::buffer_types<PodType>::container_type
785
buffer(boost::array<PodType, N>& data, std::size_t max_size_in_bytes)
787
typedef typename asio::detail::buffer_types<PodType>::buffer_type
789
typedef typename asio::detail::buffer_types<PodType>::container_type
791
return container_type(
792
buffer_type(data.c_array(),
793
data.size() * sizeof(PodType) < max_size_in_bytes
794
? data.size() * sizeof(PodType) : max_size_in_bytes));
797
#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
798
// || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
800
/// Create a new modifiable buffer that represents the given POD array.
802
* @returns A mutable_buffers_1 value equivalent to:
803
* @code mutable_buffers_1(
805
* data.size() * sizeof(PodType)); @endcode
807
template <typename PodType, std::size_t N>
808
inline mutable_buffers_1 buffer(boost::array<PodType, N>& data)
810
return mutable_buffers_1(
811
mutable_buffer(data.c_array(), data.size() * sizeof(PodType)));
814
/// Create a new modifiable buffer that represents the given POD array.
816
* @returns A mutable_buffers_1 value equivalent to:
817
* @code mutable_buffers_1(
819
* min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
821
template <typename PodType, std::size_t N>
822
inline mutable_buffers_1 buffer(boost::array<PodType, N>& data,
823
std::size_t max_size_in_bytes)
825
return mutable_buffers_1(
826
mutable_buffer(data.c_array(),
827
data.size() * sizeof(PodType) < max_size_in_bytes
828
? data.size() * sizeof(PodType) : max_size_in_bytes));
831
/// Create a new non-modifiable buffer that represents the given POD array.
833
* @returns A const_buffers_1 value equivalent to:
834
* @code const_buffers_1(
836
* data.size() * sizeof(PodType)); @endcode
838
template <typename PodType, std::size_t N>
839
inline const_buffers_1 buffer(boost::array<const PodType, N>& data)
841
return const_buffers_1(
842
const_buffer(data.data(), data.size() * sizeof(PodType)));
845
/// Create a new non-modifiable buffer that represents the given POD array.
847
* @returns A const_buffers_1 value equivalent to:
848
* @code const_buffers_1(
850
* min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
852
template <typename PodType, std::size_t N>
853
inline const_buffers_1 buffer(boost::array<const PodType, N>& data,
854
std::size_t max_size_in_bytes)
856
return const_buffers_1(
857
const_buffer(data.data(),
858
data.size() * sizeof(PodType) < max_size_in_bytes
859
? data.size() * sizeof(PodType) : max_size_in_bytes));
862
#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
863
// || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
865
/// Create a new non-modifiable buffer that represents the given POD array.
867
* @returns A const_buffers_1 value equivalent to:
868
* @code const_buffers_1(
870
* data.size() * sizeof(PodType)); @endcode
872
template <typename PodType, std::size_t N>
873
inline const_buffers_1 buffer(const boost::array<PodType, N>& data)
875
return const_buffers_1(
876
const_buffer(data.data(), data.size() * sizeof(PodType)));
879
/// Create a new non-modifiable buffer that represents the given POD array.
881
* @returns A const_buffers_1 value equivalent to:
882
* @code const_buffers_1(
884
* min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
886
template <typename PodType, std::size_t N>
887
inline const_buffers_1 buffer(const boost::array<PodType, N>& data,
888
std::size_t max_size_in_bytes)
890
return const_buffers_1(
891
const_buffer(data.data(),
892
data.size() * sizeof(PodType) < max_size_in_bytes
893
? data.size() * sizeof(PodType) : max_size_in_bytes));
896
/// Create a new modifiable buffer that represents the given POD vector.
898
* @returns A mutable_buffers_1 value equivalent to:
899
* @code mutable_buffers_1(
900
* data.size() ? &data[0] : 0,
901
* data.size() * sizeof(PodType)); @endcode
903
* @note The buffer is invalidated by any vector operation that would also
904
* invalidate iterators.
906
template <typename PodType, typename Allocator>
907
inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data)
909
return mutable_buffers_1(
910
mutable_buffer(data.size() ? &data[0] : 0, data.size() * sizeof(PodType)
911
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
912
, detail::buffer_debug_check<
913
typename std::vector<PodType, Allocator>::iterator
915
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
919
/// Create a new modifiable buffer that represents the given POD vector.
921
* @returns A mutable_buffers_1 value equivalent to:
922
* @code mutable_buffers_1(
923
* data.size() ? &data[0] : 0,
924
* min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
926
* @note The buffer is invalidated by any vector operation that would also
927
* invalidate iterators.
929
template <typename PodType, typename Allocator>
930
inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data,
931
std::size_t max_size_in_bytes)
933
return mutable_buffers_1(
934
mutable_buffer(data.size() ? &data[0] : 0,
935
data.size() * sizeof(PodType) < max_size_in_bytes
936
? data.size() * sizeof(PodType) : max_size_in_bytes
937
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
938
, detail::buffer_debug_check<
939
typename std::vector<PodType, Allocator>::iterator
941
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
945
/// Create a new non-modifiable buffer that represents the given POD vector.
947
* @returns A const_buffers_1 value equivalent to:
948
* @code const_buffers_1(
949
* data.size() ? &data[0] : 0,
950
* data.size() * sizeof(PodType)); @endcode
952
* @note The buffer is invalidated by any vector operation that would also
953
* invalidate iterators.
955
template <typename PodType, typename Allocator>
956
inline const_buffers_1 buffer(
957
const std::vector<PodType, Allocator>& data)
959
return const_buffers_1(
960
const_buffer(data.size() ? &data[0] : 0, data.size() * sizeof(PodType)
961
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
962
, detail::buffer_debug_check<
963
typename std::vector<PodType, Allocator>::const_iterator
965
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
969
/// Create a new non-modifiable buffer that represents the given POD vector.
971
* @returns A const_buffers_1 value equivalent to:
972
* @code const_buffers_1(
973
* data.size() ? &data[0] : 0,
974
* min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
976
* @note The buffer is invalidated by any vector operation that would also
977
* invalidate iterators.
979
template <typename PodType, typename Allocator>
980
inline const_buffers_1 buffer(
981
const std::vector<PodType, Allocator>& data, std::size_t max_size_in_bytes)
983
return const_buffers_1(
984
const_buffer(data.size() ? &data[0] : 0,
985
data.size() * sizeof(PodType) < max_size_in_bytes
986
? data.size() * sizeof(PodType) : max_size_in_bytes
987
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
988
, detail::buffer_debug_check<
989
typename std::vector<PodType, Allocator>::const_iterator
991
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
995
/// Create a new non-modifiable buffer that represents the given string.
997
* @returns <tt>const_buffers_1(data.data(), data.size())</tt>.
999
* @note The buffer is invalidated by any non-const operation called on the
1000
* given string object.
1002
inline const_buffers_1 buffer(const std::string& data)
1004
return const_buffers_1(const_buffer(data.data(), data.size()
1005
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
1006
, detail::buffer_debug_check<std::string::const_iterator>(data.begin())
1007
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
1011
/// Create a new non-modifiable buffer that represents the given string.
1013
* @returns A const_buffers_1 value equivalent to:
1014
* @code const_buffers_1(
1016
* min(data.size(), max_size_in_bytes)); @endcode
1018
* @note The buffer is invalidated by any non-const operation called on the
1019
* given string object.
1021
inline const_buffers_1 buffer(const std::string& data,
1022
std::size_t max_size_in_bytes)
1024
return const_buffers_1(
1025
const_buffer(data.data(),
1026
data.size() < max_size_in_bytes
1027
? data.size() : max_size_in_bytes
1028
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
1029
, detail::buffer_debug_check<std::string::const_iterator>(data.begin())
1030
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
1038
#include "asio/detail/pop_options.hpp"
1040
#endif // ASIO_BUFFER_HPP