Realistic 3D camera system
3D camera system components
buffer.hpp
Go to the documentation of this file.
1 //
2 // buffer.hpp
3 // ~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
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)
9 //
10 
11 #ifndef ASIO_BUFFER_HPP
12 #define ASIO_BUFFER_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 
18 #include "asio/detail/config.hpp"
19 #include <cstddef>
20 #include <cstring>
21 #include <string>
22 #include <vector>
24 
25 #if defined(ASIO_MSVC)
26 # if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0)
27 # if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
28 # define ASIO_ENABLE_BUFFER_DEBUGGING
29 # endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
30 # endif // defined(_HAS_ITERATOR_DEBUGGING)
31 #endif // defined(ASIO_MSVC)
32 
33 #if defined(__GNUC__)
34 # if defined(_GLIBCXX_DEBUG)
35 # if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
36 # define ASIO_ENABLE_BUFFER_DEBUGGING
37 # endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
38 # endif // defined(_GLIBCXX_DEBUG)
39 #endif // defined(__GNUC__)
40 
41 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
42 # include "asio/detail/function.hpp"
43 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
44 
45 #if defined(ASIO_HAS_BOOST_WORKAROUND)
46 # include <boost/detail/workaround.hpp>
47 # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) \
48  || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
49 # define ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND
50 # endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
51  // || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
52 #endif // defined(ASIO_HAS_BOOST_WORKAROUND)
53 
54 #if defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)
56 #endif // defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)
57 
59 
60 namespace asio {
61 
62 class mutable_buffer;
63 class const_buffer;
64 
65 namespace detail {
66 void* buffer_cast_helper(const mutable_buffer&);
67 const void* buffer_cast_helper(const const_buffer&);
68 std::size_t buffer_size_helper(const mutable_buffer&);
69 std::size_t buffer_size_helper(const const_buffer&);
70 } // namespace detail
71 
73 
92 {
93 public:
96  : data_(0),
97  size_(0)
98  {
99  }
100 
102  mutable_buffer(void* data, std::size_t size)
103  : data_(data),
104  size_(size)
105  {
106  }
107 
108 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
109  mutable_buffer(void* data, std::size_t size,
110  asio::detail::function<void()> debug_check)
111  : data_(data),
112  size_(size),
113  debug_check_(debug_check)
114  {
115  }
116 
117  const asio::detail::function<void()>& get_debug_check() const
118  {
119  return debug_check_;
120  }
121 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
122 
123 private:
125  const mutable_buffer& b);
126  friend std::size_t asio::detail::buffer_size_helper(
127  const mutable_buffer& b);
128 
129  void* data_;
130  std::size_t size_;
131 
132 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
133  asio::detail::function<void()> debug_check_;
134 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
135 };
136 
137 namespace detail {
138 
139 inline void* buffer_cast_helper(const mutable_buffer& b)
140 {
141 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
142  if (b.size_ && b.debug_check_)
143  b.debug_check_();
144 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
145  return b.data_;
146 }
147 
148 inline std::size_t buffer_size_helper(const mutable_buffer& b)
149 {
150  return b.size_;
151 }
152 
153 } // namespace detail
154 
158  : public mutable_buffer
159 {
160 public:
163 
166 
168  mutable_buffers_1(void* data, std::size_t size)
169  : mutable_buffer(data, size)
170  {
171  }
172 
175  : mutable_buffer(b)
176  {
177  }
178 
180  const_iterator begin() const
181  {
182  return this;
183  }
184 
186  const_iterator end() const
187  {
188  return begin() + 1;
189  }
190 };
191 
193 
212 {
213 public:
216  : data_(0),
217  size_(0)
218  {
219  }
220 
222  const_buffer(const void* data, std::size_t size)
223  : data_(data),
224  size_(size)
225  {
226  }
227 
230  : data_(asio::detail::buffer_cast_helper(b)),
231  size_(asio::detail::buffer_size_helper(b))
232 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
233  , debug_check_(b.get_debug_check())
234 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
235  {
236  }
237 
238 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
239  const_buffer(const void* data, std::size_t size,
240  asio::detail::function<void()> debug_check)
241  : data_(data),
242  size_(size),
243  debug_check_(debug_check)
244  {
245  }
246 
247  const asio::detail::function<void()>& get_debug_check() const
248  {
249  return debug_check_;
250  }
251 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
252 
253 private:
254  friend const void* asio::detail::buffer_cast_helper(
255  const const_buffer& b);
256  friend std::size_t asio::detail::buffer_size_helper(
257  const const_buffer& b);
258 
259  const void* data_;
260  std::size_t size_;
261 
262 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
263  asio::detail::function<void()> debug_check_;
264 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
265 };
266 
267 namespace detail {
268 
269 inline const void* buffer_cast_helper(const const_buffer& b)
270 {
271 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
272  if (b.size_ && b.debug_check_)
273  b.debug_check_();
274 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
275  return b.data_;
276 }
277 
278 inline std::size_t buffer_size_helper(const const_buffer& b)
279 {
280  return b.size_;
281 }
282 
283 } // namespace detail
284 
288  : public const_buffer
289 {
290 public:
293 
295  typedef const const_buffer* const_iterator;
296 
298  const_buffers_1(const void* data, std::size_t size)
299  : const_buffer(data, size)
300  {
301  }
302 
304  explicit const_buffers_1(const const_buffer& b)
305  : const_buffer(b)
306  {
307  }
308 
310  const_iterator begin() const
311  {
312  return this;
313  }
314 
316  const_iterator end() const
317  {
318  return begin() + 1;
319  }
320 };
321 
325 {
326 public:
329 
332 
334  const_iterator begin() const
335  {
336  return &buf_;
337  }
338 
340  const_iterator end() const
341  {
342  return &buf_;
343  }
344 
345 private:
346  mutable_buffer buf_;
347 };
348 
355 
357 inline std::size_t buffer_size(const mutable_buffer& b)
358 {
359  return detail::buffer_size_helper(b);
360 }
361 
363 inline std::size_t buffer_size(const mutable_buffers_1& b)
364 {
365  return detail::buffer_size_helper(b);
366 }
367 
369 inline std::size_t buffer_size(const const_buffer& b)
370 {
371  return detail::buffer_size_helper(b);
372 }
373 
375 inline std::size_t buffer_size(const const_buffers_1& b)
376 {
377  return detail::buffer_size_helper(b);
378 }
379 
381 
385 template <typename BufferSequence>
386 inline std::size_t buffer_size(const BufferSequence& b)
387 {
388  std::size_t total_buffer_size = 0;
389 
390  typename BufferSequence::const_iterator iter = b.begin();
391  typename BufferSequence::const_iterator end = b.end();
392  for (; iter != end; ++iter)
393  total_buffer_size += detail::buffer_size_helper(*iter);
394 
395  return total_buffer_size;
396 }
397 
421 
423 template <typename PointerToPodType>
424 inline PointerToPodType buffer_cast(const mutable_buffer& b)
425 {
426  return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
427 }
428 
430 template <typename PointerToPodType>
431 inline PointerToPodType buffer_cast(const const_buffer& b)
432 {
433  return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
434 }
435 
438 
442 inline mutable_buffer operator+(const mutable_buffer& b, std::size_t start)
443 {
444  if (start > buffer_size(b))
445  return mutable_buffer();
446  char* new_data = buffer_cast<char*>(b) + start;
447  std::size_t new_size = buffer_size(b) - start;
448  return mutable_buffer(new_data, new_size
449 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
450  , b.get_debug_check()
451 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
452  );
453 }
454 
456 
459 inline mutable_buffer operator+(std::size_t start, const mutable_buffer& b)
460 {
461  if (start > buffer_size(b))
462  return mutable_buffer();
463  char* new_data = buffer_cast<char*>(b) + start;
464  std::size_t new_size = buffer_size(b) - start;
465  return mutable_buffer(new_data, new_size
466 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
467  , b.get_debug_check()
468 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
469  );
470 }
471 
473 
476 inline const_buffer operator+(const const_buffer& b, std::size_t start)
477 {
478  if (start > buffer_size(b))
479  return const_buffer();
480  const char* new_data = buffer_cast<const char*>(b) + start;
481  std::size_t new_size = buffer_size(b) - start;
482  return const_buffer(new_data, new_size
483 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
484  , b.get_debug_check()
485 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
486  );
487 }
488 
490 
493 inline const_buffer operator+(std::size_t start, const const_buffer& b)
494 {
495  if (start > buffer_size(b))
496  return const_buffer();
497  const char* new_data = buffer_cast<const char*>(b) + start;
498  std::size_t new_size = buffer_size(b) - start;
499  return const_buffer(new_data, new_size
500 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
501  , b.get_debug_check()
502 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
503  );
504 }
505 
506 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
507 namespace detail {
508 
509 template <typename Iterator>
510 class buffer_debug_check
511 {
512 public:
513  buffer_debug_check(Iterator iter)
514  : iter_(iter)
515  {
516  }
517 
518  ~buffer_debug_check()
519  {
520 #if defined(ASIO_MSVC) && (ASIO_MSVC == 1400)
521  // MSVC 8's string iterator checking may crash in a std::string::iterator
522  // object's destructor when the iterator points to an already-destroyed
523  // std::string object, unless the iterator is cleared first.
524  iter_ = Iterator();
525 #endif // defined(ASIO_MSVC) && (ASIO_MSVC == 1400)
526  }
527 
528  void operator()()
529  {
530  *iter_;
531  }
532 
533 private:
534  Iterator iter_;
535 };
536 
537 } // namespace detail
538 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
539 
701 
703 
707 {
708  return mutable_buffers_1(b);
709 }
710 
712 
719  std::size_t max_size_in_bytes)
720 {
721  return mutable_buffers_1(
722  mutable_buffer(buffer_cast<void*>(b),
723  buffer_size(b) < max_size_in_bytes
724  ? buffer_size(b) : max_size_in_bytes
725 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
726  , b.get_debug_check()
727 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
728  ));
729 }
730 
732 
736 {
737  return const_buffers_1(b);
738 }
739 
741 
748  std::size_t max_size_in_bytes)
749 {
750  return const_buffers_1(
751  const_buffer(buffer_cast<const void*>(b),
752  buffer_size(b) < max_size_in_bytes
753  ? buffer_size(b) : max_size_in_bytes
754 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
755  , b.get_debug_check()
756 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
757  ));
758 }
759 
761 
764 inline mutable_buffers_1 buffer(void* data, std::size_t size_in_bytes)
765 {
766  return mutable_buffers_1(mutable_buffer(data, size_in_bytes));
767 }
768 
770 
773 inline const_buffers_1 buffer(const void* data,
774  std::size_t size_in_bytes)
775 {
776  return const_buffers_1(const_buffer(data, size_in_bytes));
777 }
778 
780 
786 template <typename PodType, std::size_t N>
787 inline mutable_buffers_1 buffer(PodType (&data)[N])
788 {
789  return mutable_buffers_1(mutable_buffer(data, N * sizeof(PodType)));
790 }
791 
793 
799 template <typename PodType, std::size_t N>
800 inline mutable_buffers_1 buffer(PodType (&data)[N],
801  std::size_t max_size_in_bytes)
802 {
803  return mutable_buffers_1(
804  mutable_buffer(data,
805  N * sizeof(PodType) < max_size_in_bytes
806  ? N * sizeof(PodType) : max_size_in_bytes));
807 }
808 
810 
816 template <typename PodType, std::size_t N>
817 inline const_buffers_1 buffer(const PodType (&data)[N])
818 {
819  return const_buffers_1(const_buffer(data, N * sizeof(PodType)));
820 }
821 
823 
829 template <typename PodType, std::size_t N>
830 inline const_buffers_1 buffer(const PodType (&data)[N],
831  std::size_t max_size_in_bytes)
832 {
833  return const_buffers_1(
834  const_buffer(data,
835  N * sizeof(PodType) < max_size_in_bytes
836  ? N * sizeof(PodType) : max_size_in_bytes));
837 }
838 
839 #if defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)
840 
841 // Borland C++ and Sun Studio think the overloads:
842 //
843 // unspecified buffer(boost::array<PodType, N>& array ...);
844 //
845 // and
846 //
847 // unspecified buffer(boost::array<const PodType, N>& array ...);
848 //
849 // are ambiguous. This will be worked around by using a buffer_types traits
850 // class that contains typedefs for the appropriate buffer and container
851 // classes, based on whether PodType is const or non-const.
852 
853 namespace detail {
854 
855 template <bool IsConst>
856 struct buffer_types_base;
857 
858 template <>
859 struct buffer_types_base<false>
860 {
861  typedef mutable_buffer buffer_type;
862  typedef mutable_buffers_1 container_type;
863 };
864 
865 template <>
866 struct buffer_types_base<true>
867 {
868  typedef const_buffer buffer_type;
869  typedef const_buffers_1 container_type;
870 };
871 
872 template <typename PodType>
873 struct buffer_types
874  : public buffer_types_base<is_const<PodType>::value>
875 {
876 };
877 
878 } // namespace detail
879 
880 template <typename PodType, std::size_t N>
881 inline typename detail::buffer_types<PodType>::container_type
883 {
884  typedef typename asio::detail::buffer_types<PodType>::buffer_type
885  buffer_type;
886  typedef typename asio::detail::buffer_types<PodType>::container_type
887  container_type;
888  return container_type(
889  buffer_type(data.c_array(), data.size() * sizeof(PodType)));
890 }
891 
892 template <typename PodType, std::size_t N>
893 inline typename detail::buffer_types<PodType>::container_type
894 buffer(boost::array<PodType, N>& data, std::size_t max_size_in_bytes)
895 {
896  typedef typename asio::detail::buffer_types<PodType>::buffer_type
897  buffer_type;
898  typedef typename asio::detail::buffer_types<PodType>::container_type
899  container_type;
900  return container_type(
901  buffer_type(data.c_array(),
902  data.size() * sizeof(PodType) < max_size_in_bytes
903  ? data.size() * sizeof(PodType) : max_size_in_bytes));
904 }
905 
906 #else // defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)
907 
909 
915 template <typename PodType, std::size_t N>
917 {
918  return mutable_buffers_1(
919  mutable_buffer(data.c_array(), data.size() * sizeof(PodType)));
920 }
921 
923 
929 template <typename PodType, std::size_t N>
931  std::size_t max_size_in_bytes)
932 {
933  return mutable_buffers_1(
934  mutable_buffer(data.c_array(),
935  data.size() * sizeof(PodType) < max_size_in_bytes
936  ? data.size() * sizeof(PodType) : max_size_in_bytes));
937 }
938 
940 
946 template <typename PodType, std::size_t N>
948 {
949  return const_buffers_1(
950  const_buffer(data.data(), data.size() * sizeof(PodType)));
951 }
952 
954 
960 template <typename PodType, std::size_t N>
962  std::size_t max_size_in_bytes)
963 {
964  return const_buffers_1(
965  const_buffer(data.data(),
966  data.size() * sizeof(PodType) < max_size_in_bytes
967  ? data.size() * sizeof(PodType) : max_size_in_bytes));
968 }
969 
970 #endif // defined(ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)
971 
973 
979 template <typename PodType, std::size_t N>
981 {
982  return const_buffers_1(
983  const_buffer(data.data(), data.size() * sizeof(PodType)));
984 }
985 
987 
993 template <typename PodType, std::size_t N>
995  std::size_t max_size_in_bytes)
996 {
997  return const_buffers_1(
998  const_buffer(data.data(),
999  data.size() * sizeof(PodType) < max_size_in_bytes
1000  ? data.size() * sizeof(PodType) : max_size_in_bytes));
1001 }
1002 
1003 #if defined(ASIO_HAS_STD_ARRAY) || defined(GENERATING_DOCUMENTATION)
1004 
1006 
1012 template <typename PodType, std::size_t N>
1013 inline mutable_buffers_1 buffer(std::array<PodType, N>& data)
1014 {
1015  return mutable_buffers_1(
1016  mutable_buffer(data.data(), data.size() * sizeof(PodType)));
1017 }
1018 
1020 
1026 template <typename PodType, std::size_t N>
1027 inline mutable_buffers_1 buffer(std::array<PodType, N>& data,
1028  std::size_t max_size_in_bytes)
1029 {
1030  return mutable_buffers_1(
1031  mutable_buffer(data.data(),
1032  data.size() * sizeof(PodType) < max_size_in_bytes
1033  ? data.size() * sizeof(PodType) : max_size_in_bytes));
1034 }
1035 
1037 
1043 template <typename PodType, std::size_t N>
1044 inline const_buffers_1 buffer(std::array<const PodType, N>& data)
1045 {
1046  return const_buffers_1(
1047  const_buffer(data.data(), data.size() * sizeof(PodType)));
1048 }
1049 
1051 
1057 template <typename PodType, std::size_t N>
1058 inline const_buffers_1 buffer(std::array<const PodType, N>& data,
1059  std::size_t max_size_in_bytes)
1060 {
1061  return const_buffers_1(
1062  const_buffer(data.data(),
1063  data.size() * sizeof(PodType) < max_size_in_bytes
1064  ? data.size() * sizeof(PodType) : max_size_in_bytes));
1065 }
1066 
1068 
1074 template <typename PodType, std::size_t N>
1075 inline const_buffers_1 buffer(const std::array<PodType, N>& data)
1076 {
1077  return const_buffers_1(
1078  const_buffer(data.data(), data.size() * sizeof(PodType)));
1079 }
1080 
1082 
1088 template <typename PodType, std::size_t N>
1089 inline const_buffers_1 buffer(const std::array<PodType, N>& data,
1090  std::size_t max_size_in_bytes)
1091 {
1092  return const_buffers_1(
1093  const_buffer(data.data(),
1094  data.size() * sizeof(PodType) < max_size_in_bytes
1095  ? data.size() * sizeof(PodType) : max_size_in_bytes));
1096 }
1097 
1098 #endif // defined(ASIO_HAS_STD_ARRAY) || defined(GENERATING_DOCUMENTATION)
1099 
1101 
1110 template <typename PodType, typename Allocator>
1111 inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data)
1112 {
1113  return mutable_buffers_1(
1114  mutable_buffer(data.size() ? &data[0] : 0, data.size() * sizeof(PodType)
1115 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
1116  , detail::buffer_debug_check<
1117  typename std::vector<PodType, Allocator>::iterator
1118  >(data.begin())
1119 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
1120  ));
1121 }
1122 
1124 
1133 template <typename PodType, typename Allocator>
1134 inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data,
1135  std::size_t max_size_in_bytes)
1136 {
1137  return mutable_buffers_1(
1138  mutable_buffer(data.size() ? &data[0] : 0,
1139  data.size() * sizeof(PodType) < max_size_in_bytes
1140  ? data.size() * sizeof(PodType) : max_size_in_bytes
1141 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
1142  , detail::buffer_debug_check<
1143  typename std::vector<PodType, Allocator>::iterator
1144  >(data.begin())
1145 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
1146  ));
1147 }
1148 
1150 
1159 template <typename PodType, typename Allocator>
1161  const std::vector<PodType, Allocator>& data)
1162 {
1163  return const_buffers_1(
1164  const_buffer(data.size() ? &data[0] : 0, data.size() * sizeof(PodType)
1165 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
1166  , detail::buffer_debug_check<
1167  typename std::vector<PodType, Allocator>::const_iterator
1168  >(data.begin())
1169 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
1170  ));
1171 }
1172 
1174 
1183 template <typename PodType, typename Allocator>
1185  const std::vector<PodType, Allocator>& data, std::size_t max_size_in_bytes)
1186 {
1187  return const_buffers_1(
1188  const_buffer(data.size() ? &data[0] : 0,
1189  data.size() * sizeof(PodType) < max_size_in_bytes
1190  ? data.size() * sizeof(PodType) : max_size_in_bytes
1191 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
1192  , detail::buffer_debug_check<
1193  typename std::vector<PodType, Allocator>::const_iterator
1194  >(data.begin())
1195 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
1196  ));
1197 }
1198 
1200 
1206 template <typename Elem, typename Traits, typename Allocator>
1208  const std::basic_string<Elem, Traits, Allocator>& data)
1209 {
1210  return const_buffers_1(const_buffer(data.data(), data.size() * sizeof(Elem)
1211 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
1212  , detail::buffer_debug_check<
1213  typename std::basic_string<Elem, Traits, Allocator>::const_iterator
1214  >(data.begin())
1215 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
1216  ));
1217 }
1218 
1220 
1229 template <typename Elem, typename Traits, typename Allocator>
1231  const std::basic_string<Elem, Traits, Allocator>& data,
1232  std::size_t max_size_in_bytes)
1233 {
1234  return const_buffers_1(
1235  const_buffer(data.data(),
1236  data.size() * sizeof(Elem) < max_size_in_bytes
1237  ? data.size() * sizeof(Elem) : max_size_in_bytes
1238 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
1239  , detail::buffer_debug_check<
1240  typename std::basic_string<Elem, Traits, Allocator>::const_iterator
1241  >(data.begin())
1242 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
1243  ));
1244 }
1245 
1275 
1277 
1295 inline std::size_t buffer_copy(const mutable_buffer& target,
1296  const const_buffer& source)
1297 {
1298  using namespace std; // For memcpy.
1299  std::size_t target_size = buffer_size(target);
1300  std::size_t source_size = buffer_size(source);
1301  std::size_t n = target_size < source_size ? target_size : source_size;
1302  memcpy(buffer_cast<void*>(target), buffer_cast<const void*>(source), n);
1303  return n;
1304 }
1305 
1307 
1325 inline std::size_t buffer_copy(const mutable_buffer& target,
1326  const const_buffers_1& source)
1327 {
1328  return buffer_copy(target, static_cast<const const_buffer&>(source));
1329 }
1330 
1332 
1351 inline std::size_t buffer_copy(const mutable_buffer& target,
1352  const mutable_buffer& source)
1353 {
1354  return buffer_copy(target, const_buffer(source));
1355 }
1356 
1358 
1377 inline std::size_t buffer_copy(const mutable_buffer& target,
1378  const mutable_buffers_1& source)
1379 {
1380  return buffer_copy(target, const_buffer(source));
1381 }
1382 
1384 
1402 template <typename ConstBufferSequence>
1403 std::size_t buffer_copy(const mutable_buffer& target,
1404  const ConstBufferSequence& source)
1405 {
1406  std::size_t total_bytes_copied = 0;
1407 
1408  typename ConstBufferSequence::const_iterator source_iter = source.begin();
1409  typename ConstBufferSequence::const_iterator source_end = source.end();
1410 
1411  for (mutable_buffer target_buffer(target);
1412  buffer_size(target_buffer) && source_iter != source_end; ++source_iter)
1413  {
1414  const_buffer source_buffer(*source_iter);
1415  std::size_t bytes_copied = buffer_copy(target_buffer, source_buffer);
1416  total_bytes_copied += bytes_copied;
1417  target_buffer = target_buffer + bytes_copied;
1418  }
1419 
1420  return total_bytes_copied;
1421 }
1422 
1424 
1442 inline std::size_t buffer_copy(const mutable_buffers_1& target,
1443  const const_buffer& source)
1444 {
1445  return buffer_copy(static_cast<const mutable_buffer&>(target), source);
1446 }
1447 
1449 
1467 inline std::size_t buffer_copy(const mutable_buffers_1& target,
1468  const const_buffers_1& source)
1469 {
1470  return buffer_copy(static_cast<const mutable_buffer&>(target),
1471  static_cast<const const_buffer&>(source));
1472 }
1473 
1475 
1494 inline std::size_t buffer_copy(const mutable_buffers_1& target,
1495  const mutable_buffer& source)
1496 {
1497  return buffer_copy(static_cast<const mutable_buffer&>(target),
1498  const_buffer(source));
1499 }
1500 
1502 
1521 inline std::size_t buffer_copy(const mutable_buffers_1& target,
1522  const mutable_buffers_1& source)
1523 {
1524  return buffer_copy(static_cast<const mutable_buffer&>(target),
1525  const_buffer(source));
1526 }
1527 
1529 
1547 template <typename ConstBufferSequence>
1548 inline std::size_t buffer_copy(const mutable_buffers_1& target,
1549  const ConstBufferSequence& source)
1550 {
1551  return buffer_copy(static_cast<const mutable_buffer&>(target), source);
1552 }
1553 
1555 
1573 template <typename MutableBufferSequence>
1574 std::size_t buffer_copy(const MutableBufferSequence& target,
1575  const const_buffer& source)
1576 {
1577  std::size_t total_bytes_copied = 0;
1578 
1579  typename MutableBufferSequence::const_iterator target_iter = target.begin();
1580  typename MutableBufferSequence::const_iterator target_end = target.end();
1581 
1582  for (const_buffer source_buffer(source);
1583  buffer_size(source_buffer) && target_iter != target_end; ++target_iter)
1584  {
1585  mutable_buffer target_buffer(*target_iter);
1586  std::size_t bytes_copied = buffer_copy(target_buffer, source_buffer);
1587  total_bytes_copied += bytes_copied;
1588  source_buffer = source_buffer + bytes_copied;
1589  }
1590 
1591  return total_bytes_copied;
1592 }
1593 
1595 
1613 template <typename MutableBufferSequence>
1614 inline std::size_t buffer_copy(const MutableBufferSequence& target,
1615  const const_buffers_1& source)
1616 {
1617  return buffer_copy(target, static_cast<const const_buffer&>(source));
1618 }
1619 
1621 
1640 template <typename MutableBufferSequence>
1641 inline std::size_t buffer_copy(const MutableBufferSequence& target,
1642  const mutable_buffer& source)
1643 {
1644  return buffer_copy(target, const_buffer(source));
1645 }
1646 
1648 
1667 template <typename MutableBufferSequence>
1668 inline std::size_t buffer_copy(const MutableBufferSequence& target,
1669  const mutable_buffers_1& source)
1670 {
1671  return buffer_copy(target, const_buffer(source));
1672 }
1673 
1675 
1693 template <typename MutableBufferSequence, typename ConstBufferSequence>
1694 std::size_t buffer_copy(const MutableBufferSequence& target,
1695  const ConstBufferSequence& source)
1696 {
1697  std::size_t total_bytes_copied = 0;
1698 
1699  typename MutableBufferSequence::const_iterator target_iter = target.begin();
1700  typename MutableBufferSequence::const_iterator target_end = target.end();
1701  std::size_t target_buffer_offset = 0;
1702 
1703  typename ConstBufferSequence::const_iterator source_iter = source.begin();
1704  typename ConstBufferSequence::const_iterator source_end = source.end();
1705  std::size_t source_buffer_offset = 0;
1706 
1707  while (target_iter != target_end && source_iter != source_end)
1708  {
1709  mutable_buffer target_buffer =
1710  mutable_buffer(*target_iter) + target_buffer_offset;
1711 
1712  const_buffer source_buffer =
1713  const_buffer(*source_iter) + source_buffer_offset;
1714 
1715  std::size_t bytes_copied = buffer_copy(target_buffer, source_buffer);
1716  total_bytes_copied += bytes_copied;
1717 
1718  if (bytes_copied == buffer_size(target_buffer))
1719  {
1720  ++target_iter;
1721  target_buffer_offset = 0;
1722  }
1723  else
1724  target_buffer_offset += bytes_copied;
1725 
1726  if (bytes_copied == buffer_size(source_buffer))
1727  {
1728  ++source_iter;
1729  source_buffer_offset = 0;
1730  }
1731  else
1732  source_buffer_offset += bytes_copied;
1733  }
1734 
1735  return total_bytes_copied;
1736 }
1737 
1739 
1761 inline std::size_t buffer_copy(const mutable_buffer& target,
1762  const const_buffer& source, std::size_t max_bytes_to_copy)
1763 {
1764  return buffer_copy(buffer(target, max_bytes_to_copy), source);
1765 }
1766 
1768 
1790 inline std::size_t buffer_copy(const mutable_buffer& target,
1791  const const_buffers_1& source, std::size_t max_bytes_to_copy)
1792 {
1793  return buffer_copy(buffer(target, max_bytes_to_copy), source);
1794 }
1795 
1797 
1820 inline std::size_t buffer_copy(const mutable_buffer& target,
1821  const mutable_buffer& source, std::size_t max_bytes_to_copy)
1822 {
1823  return buffer_copy(buffer(target, max_bytes_to_copy), source);
1824 }
1825 
1827 
1850 inline std::size_t buffer_copy(const mutable_buffer& target,
1851  const mutable_buffers_1& source, std::size_t max_bytes_to_copy)
1852 {
1853  return buffer_copy(buffer(target, max_bytes_to_copy), source);
1854 }
1855 
1858 
1880 template <typename ConstBufferSequence>
1881 inline std::size_t buffer_copy(const mutable_buffer& target,
1882  const ConstBufferSequence& source, std::size_t max_bytes_to_copy)
1883 {
1884  return buffer_copy(buffer(target, max_bytes_to_copy), source);
1885 }
1886 
1888 
1910 inline std::size_t buffer_copy(const mutable_buffers_1& target,
1911  const const_buffer& source, std::size_t max_bytes_to_copy)
1912 {
1913  return buffer_copy(buffer(target, max_bytes_to_copy), source);
1914 }
1915 
1917 
1939 inline std::size_t buffer_copy(const mutable_buffers_1& target,
1940  const const_buffers_1& source, std::size_t max_bytes_to_copy)
1941 {
1942  return buffer_copy(buffer(target, max_bytes_to_copy), source);
1943 }
1944 
1946 
1969 inline std::size_t buffer_copy(const mutable_buffers_1& target,
1970  const mutable_buffer& source, std::size_t max_bytes_to_copy)
1971 {
1972  return buffer_copy(buffer(target, max_bytes_to_copy), source);
1973 }
1974 
1976 
1999 inline std::size_t buffer_copy(const mutable_buffers_1& target,
2000  const mutable_buffers_1& source, std::size_t max_bytes_to_copy)
2001 {
2002  return buffer_copy(buffer(target, max_bytes_to_copy), source);
2003 }
2004 
2007 
2029 template <typename ConstBufferSequence>
2030 inline std::size_t buffer_copy(const mutable_buffers_1& target,
2031  const ConstBufferSequence& source, std::size_t max_bytes_to_copy)
2032 {
2033  return buffer_copy(buffer(target, max_bytes_to_copy), source);
2034 }
2035 
2038 
2060 template <typename MutableBufferSequence>
2061 inline std::size_t buffer_copy(const MutableBufferSequence& target,
2062  const const_buffer& source, std::size_t max_bytes_to_copy)
2063 {
2064  return buffer_copy(target, buffer(source, max_bytes_to_copy));
2065 }
2066 
2069 
2091 template <typename MutableBufferSequence>
2092 inline std::size_t buffer_copy(const MutableBufferSequence& target,
2093  const const_buffers_1& source, std::size_t max_bytes_to_copy)
2094 {
2095  return buffer_copy(target, buffer(source, max_bytes_to_copy));
2096 }
2097 
2100 
2123 template <typename MutableBufferSequence>
2124 inline std::size_t buffer_copy(const MutableBufferSequence& target,
2125  const mutable_buffer& source, std::size_t max_bytes_to_copy)
2126 {
2127  return buffer_copy(target, buffer(source, max_bytes_to_copy));
2128 }
2129 
2132 
2155 template <typename MutableBufferSequence>
2156 inline std::size_t buffer_copy(const MutableBufferSequence& target,
2157  const mutable_buffers_1& source, std::size_t max_bytes_to_copy)
2158 {
2159  return buffer_copy(target, buffer(source, max_bytes_to_copy));
2160 }
2161 
2164 
2186 template <typename MutableBufferSequence, typename ConstBufferSequence>
2187 std::size_t buffer_copy(const MutableBufferSequence& target,
2188  const ConstBufferSequence& source, std::size_t max_bytes_to_copy)
2189 {
2190  std::size_t total_bytes_copied = 0;
2191 
2192  typename MutableBufferSequence::const_iterator target_iter = target.begin();
2193  typename MutableBufferSequence::const_iterator target_end = target.end();
2194  std::size_t target_buffer_offset = 0;
2195 
2196  typename ConstBufferSequence::const_iterator source_iter = source.begin();
2197  typename ConstBufferSequence::const_iterator source_end = source.end();
2198  std::size_t source_buffer_offset = 0;
2199 
2200  while (total_bytes_copied != max_bytes_to_copy
2201  && target_iter != target_end && source_iter != source_end)
2202  {
2203  mutable_buffer target_buffer =
2204  mutable_buffer(*target_iter) + target_buffer_offset;
2205 
2206  const_buffer source_buffer =
2207  const_buffer(*source_iter) + source_buffer_offset;
2208 
2209  std::size_t bytes_copied = buffer_copy(target_buffer,
2210  source_buffer, max_bytes_to_copy - total_bytes_copied);
2211  total_bytes_copied += bytes_copied;
2212 
2213  if (bytes_copied == buffer_size(target_buffer))
2214  {
2215  ++target_iter;
2216  target_buffer_offset = 0;
2217  }
2218  else
2219  target_buffer_offset += bytes_copied;
2220 
2221  if (bytes_copied == buffer_size(source_buffer))
2222  {
2223  ++source_iter;
2224  source_buffer_offset = 0;
2225  }
2226  else
2227  source_buffer_offset += bytes_copied;
2228  }
2229 
2230  return total_bytes_copied;
2231 }
2232 
2235 } // namespace asio
2236 
2237 #include "asio/detail/pop_options.hpp"
2238 
2239 #endif // ASIO_BUFFER_HPP
mutable_buffer(void *data, std::size_t size)
Construct a buffer to represent a given memory range.
Definition: buffer.hpp:102
const_iterator end() const
Get a random-access iterator for one past the last element.
Definition: buffer.hpp:340
mutable_buffers_1(const mutable_buffer &b)
Construct to represent a single modifiable buffer.
Definition: buffer.hpp:174
std::size_t buffer_size_helper(const mutable_buffer &)
Definition: buffer.hpp:148
mutable_buffer operator+(std::size_t start, const mutable_buffer &b)
Create a new modifiable buffer that is offset from the start of another.
Definition: buffer.hpp:459
Holds a buffer that cannot be modified.
Definition: buffer.hpp:211
SocketService Iterator begin
Definition: connect.hpp:521
mutable_buffer value_type
The type for each element in the list of buffers.
Definition: buffer.hpp:162
const_buffer()
Construct an empty buffer.
Definition: buffer.hpp:215
STL namespace.
mutable_buffers_1 buffer(const mutable_buffer &b)
Create a new modifiable buffer from an existing buffer.
Definition: buffer.hpp:706
const_buffer value_type
The type for each element in the list of buffers.
Definition: buffer.hpp:292
mutable_buffer()
Construct an empty buffer.
Definition: buffer.hpp:95
const_iterator begin() const
Get a random-access iterator to the first element.
Definition: buffer.hpp:310
const_buffer operator+(std::size_t start, const const_buffer &b)
Create a new non-modifiable buffer that is offset from the start of another.
Definition: buffer.hpp:493
void * buffer_cast_helper(const mutable_buffer &)
Definition: buffer.hpp:139
mutable_buffer operator+(const mutable_buffer &b, std::size_t start)
Create a new modifiable buffer that is offset from the start of another.
Definition: buffer.hpp:442
asio::basic_streambuf< Allocator > & b
Definition: read.hpp:702
const mutable_buffer * const_iterator
A random-access iterator type that may be used to read elements.
Definition: buffer.hpp:331
std::size_t buffer_size(const mutable_buffer &b)
Get the number of bytes in a modifiable buffer.
Definition: buffer.hpp:357
PointerToPodType buffer_cast(const mutable_buffer &b)
Cast a non-modifiable buffer to a specified pointer to POD type.
Definition: buffer.hpp:424
const_iterator begin() const
Get a random-access iterator to the first element.
Definition: buffer.hpp:180
mutable_buffers_1(void *data, std::size_t size)
Construct to represent a given memory range.
Definition: buffer.hpp:168
const_buffers_1(const void *data, std::size_t size)
Construct to represent a given memory range.
Definition: buffer.hpp:298
const_iterator begin() const
Get a random-access iterator to the first element.
Definition: buffer.hpp:334
Holds a buffer that can be modified.
Definition: buffer.hpp:91
const_iterator end() const
Get a random-access iterator for one past the last element.
Definition: buffer.hpp:186
const_buffer(const mutable_buffer &b)
Construct a non-modifiable buffer from a modifiable one.
Definition: buffer.hpp:229
mutable_buffer value_type
The type for each element in the list of buffers.
Definition: buffer.hpp:328
const_buffer(const void *data, std::size_t size)
Construct a buffer to represent a given memory range.
Definition: buffer.hpp:222
SocketService Iterator Iterator end
Definition: connect.hpp:592
const mutable_buffer * const_iterator
A random-access iterator type that may be used to read elements.
Definition: buffer.hpp:165
const const_buffer * const_iterator
A random-access iterator type that may be used to read elements.
Definition: buffer.hpp:295
const_iterator end() const
Get a random-access iterator for one past the last element.
Definition: buffer.hpp:316
std::size_t buffer_copy(const mutable_buffer &target, const const_buffer &source)
Copies bytes from a source buffer to a target buffer.
Definition: buffer.hpp:1295
const_buffers_1(const const_buffer &b)
Construct to represent a single non-modifiable buffer.
Definition: buffer.hpp:304
const_buffer operator+(const const_buffer &b, std::size_t start)
Create a new non-modifiable buffer that is offset from the start of another.
Definition: buffer.hpp:476