buffer.hpp
Go to the documentation of this file.
00001 //
00002 // buffer.hpp
00003 // ~~~~~~~~~~
00004 //
00005 // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
00006 //
00007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
00008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
00009 //
00010 
00011 #ifndef ASIO_BUFFER_HPP
00012 #define ASIO_BUFFER_HPP
00013 
00014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
00015 # pragma once
00016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
00017 
00018 #include "asio/detail/push_options.hpp"
00019 
00020 #include "asio/detail/push_options.hpp"
00021 #include <cstddef>
00022 #include <boost/config.hpp>
00023 #include <boost/array.hpp>
00024 #include <boost/type_traits/is_const.hpp>
00025 #include <string>
00026 #include <vector>
00027 #include "asio/detail/pop_options.hpp"
00028 
00029 #if defined(BOOST_MSVC)
00030 # if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0)
00031 #  if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
00032 #   define ASIO_ENABLE_BUFFER_DEBUGGING
00033 #  endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
00034 # endif // defined(_HAS_ITERATOR_DEBUGGING)
00035 #endif // defined(BOOST_MSVC)
00036 
00037 #if defined(__GNUC__)
00038 # if defined(_GLIBCXX_DEBUG)
00039 #  if !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
00040 #   define ASIO_ENABLE_BUFFER_DEBUGGING
00041 #  endif // !defined(ASIO_DISABLE_BUFFER_DEBUGGING)
00042 # endif // defined(_GLIBCXX_DEBUG)
00043 #endif // defined(__GNUC__)
00044 
00045 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
00046 # include "asio/detail/push_options.hpp"
00047 # include <boost/function.hpp>
00048 # include "asio/detail/pop_options.hpp"
00049 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
00050 
00051 namespace asio {
00052 
00053 class mutable_buffer;
00054 class const_buffer;
00055 
00056 namespace detail {
00057 void* buffer_cast_helper(const mutable_buffer&);
00058 const void* buffer_cast_helper(const const_buffer&);
00059 std::size_t buffer_size_helper(const mutable_buffer&);
00060 std::size_t buffer_size_helper(const const_buffer&);
00061 } // namespace detail
00062 
00064 
00069 class mutable_buffer
00070 {
00071 public:
00073   mutable_buffer()
00074     : data_(0),
00075       size_(0)
00076   {
00077   }
00078 
00080   mutable_buffer(void* data, std::size_t size)
00081     : data_(data),
00082       size_(size)
00083   {
00084   }
00085 
00086 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
00087   mutable_buffer(void* data, std::size_t size,
00088       boost::function<void()> debug_check)
00089     : data_(data),
00090       size_(size),
00091       debug_check_(debug_check)
00092   {
00093   }
00094 
00095   const boost::function<void()>& get_debug_check() const
00096   {
00097     return debug_check_;
00098   }
00099 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
00100 
00101 private:
00102   friend void* asio::detail::buffer_cast_helper(
00103       const mutable_buffer& b);
00104   friend std::size_t asio::detail::buffer_size_helper(
00105       const mutable_buffer& b);
00106 
00107   void* data_;
00108   std::size_t size_;
00109 
00110 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
00111   boost::function<void()> debug_check_;
00112 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
00113 };
00114 
00115 namespace detail {
00116 
00117 inline void* buffer_cast_helper(const mutable_buffer& b)
00118 {
00119 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
00120   if (b.size_ && b.debug_check_)
00121     b.debug_check_();
00122 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
00123   return b.data_;
00124 }
00125 
00126 inline std::size_t buffer_size_helper(const mutable_buffer& b)
00127 {
00128   return b.size_;
00129 }
00130 
00131 } // namespace detail
00132 
00134 
00137 template <typename PointerToPodType>
00138 inline PointerToPodType buffer_cast(const mutable_buffer& b)
00139 {
00140   return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
00141 }
00142 
00144 
00147 inline std::size_t buffer_size(const mutable_buffer& b)
00148 {
00149   return detail::buffer_size_helper(b);
00150 }
00151 
00153 
00156 inline mutable_buffer operator+(const mutable_buffer& b, std::size_t start)
00157 {
00158   if (start > buffer_size(b))
00159     return mutable_buffer();
00160   char* new_data = buffer_cast<char*>(b) + start;
00161   std::size_t new_size = buffer_size(b) - start;
00162   return mutable_buffer(new_data, new_size
00163 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
00164       , b.get_debug_check()
00165 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
00166       );
00167 }
00168 
00170 
00173 inline mutable_buffer operator+(std::size_t start, const mutable_buffer& b)
00174 {
00175   if (start > buffer_size(b))
00176     return mutable_buffer();
00177   char* new_data = buffer_cast<char*>(b) + start;
00178   std::size_t new_size = buffer_size(b) - start;
00179   return mutable_buffer(new_data, new_size
00180 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
00181       , b.get_debug_check()
00182 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
00183       );
00184 }
00185 
00188 class mutable_buffers_1
00189   : public mutable_buffer
00190 {
00191 public:
00193   typedef mutable_buffer value_type;
00194 
00196   typedef const mutable_buffer* const_iterator;
00197 
00199   mutable_buffers_1(void* data, std::size_t size)
00200     : mutable_buffer(data, size)
00201   {
00202   }
00203 
00205   explicit mutable_buffers_1(const mutable_buffer& b)
00206     : mutable_buffer(b)
00207   {
00208   }
00209 
00211   const_iterator begin() const
00212   {
00213     return this;
00214   }
00215 
00217   const_iterator end() const
00218   {
00219     return begin() + 1;
00220   }
00221 };
00222 
00224 
00229 class const_buffer
00230 {
00231 public:
00233   const_buffer()
00234     : data_(0),
00235       size_(0)
00236   {
00237   }
00238 
00240   const_buffer(const void* data, std::size_t size)
00241     : data_(data),
00242       size_(size)
00243   {
00244   }
00245 
00247   const_buffer(const mutable_buffer& b)
00248     : data_(asio::detail::buffer_cast_helper(b)),
00249       size_(asio::detail::buffer_size_helper(b))
00250 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
00251       , debug_check_(b.get_debug_check())
00252 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
00253   {
00254   }
00255 
00256 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
00257   const_buffer(const void* data, std::size_t size,
00258       boost::function<void()> debug_check)
00259     : data_(data),
00260       size_(size),
00261       debug_check_(debug_check)
00262   {
00263   }
00264 
00265   const boost::function<void()>& get_debug_check() const
00266   {
00267     return debug_check_;
00268   }
00269 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
00270 
00271 private:
00272   friend const void* asio::detail::buffer_cast_helper(
00273       const const_buffer& b);
00274   friend std::size_t asio::detail::buffer_size_helper(
00275       const const_buffer& b);
00276 
00277   const void* data_;
00278   std::size_t size_;
00279 
00280 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
00281   boost::function<void()> debug_check_;
00282 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
00283 };
00284 
00285 namespace detail {
00286 
00287 inline const void* buffer_cast_helper(const const_buffer& b)
00288 {
00289 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
00290   if (b.size_ && b.debug_check_)
00291     b.debug_check_();
00292 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
00293   return b.data_;
00294 }
00295 
00296 inline std::size_t buffer_size_helper(const const_buffer& b)
00297 {
00298   return b.size_;
00299 }
00300 
00301 } // namespace detail
00302 
00304 
00307 template <typename PointerToPodType>
00308 inline PointerToPodType buffer_cast(const const_buffer& b)
00309 {
00310   return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
00311 }
00312 
00314 
00317 inline std::size_t buffer_size(const const_buffer& b)
00318 {
00319   return detail::buffer_size_helper(b);
00320 }
00321 
00323 
00326 inline const_buffer operator+(const const_buffer& b, std::size_t start)
00327 {
00328   if (start > buffer_size(b))
00329     return const_buffer();
00330   const char* new_data = buffer_cast<const char*>(b) + start;
00331   std::size_t new_size = buffer_size(b) - start;
00332   return const_buffer(new_data, new_size
00333 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
00334       , b.get_debug_check()
00335 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
00336       );
00337 }
00338 
00340 
00343 inline const_buffer operator+(std::size_t start, const const_buffer& b)
00344 {
00345   if (start > buffer_size(b))
00346     return const_buffer();
00347   const char* new_data = buffer_cast<const char*>(b) + start;
00348   std::size_t new_size = buffer_size(b) - start;
00349   return const_buffer(new_data, new_size
00350 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
00351       , b.get_debug_check()
00352 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
00353       );
00354 }
00355 
00358 class const_buffers_1
00359   : public const_buffer
00360 {
00361 public:
00363   typedef const_buffer value_type;
00364 
00366   typedef const const_buffer* const_iterator;
00367 
00369   const_buffers_1(const void* data, std::size_t size)
00370     : const_buffer(data, size)
00371   {
00372   }
00373 
00375   explicit const_buffers_1(const const_buffer& b)
00376     : const_buffer(b)
00377   {
00378   }
00379 
00381   const_iterator begin() const
00382   {
00383     return this;
00384   }
00385 
00387   const_iterator end() const
00388   {
00389     return begin() + 1;
00390   }
00391 };
00392 
00395 class null_buffers
00396 {
00397 public:
00399   typedef mutable_buffer value_type;
00400 
00402   typedef const mutable_buffer* const_iterator;
00403 
00405   const_iterator begin() const
00406   {
00407     return &buf_;
00408   }
00409 
00411   const_iterator end() const
00412   {
00413     return &buf_;
00414   }
00415 
00416 private:
00417   mutable_buffer buf_;
00418 };
00419 
00420 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
00421 namespace detail {
00422 
00423 template <typename Iterator>
00424 class buffer_debug_check
00425 {
00426 public:
00427   buffer_debug_check(Iterator iter)
00428     : iter_(iter)
00429   {
00430   }
00431 
00432   ~buffer_debug_check()
00433   {
00434 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
00435     // MSVC's string iterator checking may crash in a std::string::iterator
00436     // object's destructor when the iterator points to an already-destroyed
00437     // std::string object, unless the iterator is cleared first.
00438     iter_ = Iterator();
00439 #endif // BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
00440   }
00441 
00442   void operator()()
00443   {
00444     *iter_;
00445   }
00446 
00447 private:
00448   Iterator iter_;
00449 };
00450 
00451 } // namespace detail
00452 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
00453 
00591 
00593 
00596 inline mutable_buffers_1 buffer(const mutable_buffer& b)
00597 {
00598   return mutable_buffers_1(b);
00599 }
00600 
00602 
00608 inline mutable_buffers_1 buffer(const mutable_buffer& b,
00609     std::size_t max_size_in_bytes)
00610 {
00611   return mutable_buffers_1(
00612       mutable_buffer(buffer_cast<void*>(b),
00613         buffer_size(b) < max_size_in_bytes
00614         ? buffer_size(b) : max_size_in_bytes
00615 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
00616         , b.get_debug_check()
00617 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
00618         ));
00619 }
00620 
00622 
00625 inline const_buffers_1 buffer(const const_buffer& b)
00626 {
00627   return const_buffers_1(b);
00628 }
00629 
00631 
00637 inline const_buffers_1 buffer(const const_buffer& b,
00638     std::size_t max_size_in_bytes)
00639 {
00640   return const_buffers_1(
00641       const_buffer(buffer_cast<const void*>(b),
00642         buffer_size(b) < max_size_in_bytes
00643         ? buffer_size(b) : max_size_in_bytes
00644 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
00645         , b.get_debug_check()
00646 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
00647         ));
00648 }
00649 
00651 
00654 inline mutable_buffers_1 buffer(void* data, std::size_t size_in_bytes)
00655 {
00656   return mutable_buffers_1(mutable_buffer(data, size_in_bytes));
00657 }
00658 
00660 
00663 inline const_buffers_1 buffer(const void* data,
00664     std::size_t size_in_bytes)
00665 {
00666   return const_buffers_1(const_buffer(data, size_in_bytes));
00667 }
00668 
00670 
00676 template <typename PodType, std::size_t N>
00677 inline mutable_buffers_1 buffer(PodType (&data)[N])
00678 {
00679   return mutable_buffers_1(mutable_buffer(data, N * sizeof(PodType)));
00680 }
00681  
00683 
00689 template <typename PodType, std::size_t N>
00690 inline mutable_buffers_1 buffer(PodType (&data)[N],
00691     std::size_t max_size_in_bytes)
00692 {
00693   return mutable_buffers_1(
00694       mutable_buffer(data,
00695         N * sizeof(PodType) < max_size_in_bytes
00696         ? N * sizeof(PodType) : max_size_in_bytes));
00697 }
00698  
00700 
00706 template <typename PodType, std::size_t N>
00707 inline const_buffers_1 buffer(const PodType (&data)[N])
00708 {
00709   return const_buffers_1(const_buffer(data, N * sizeof(PodType)));
00710 }
00711 
00713 
00719 template <typename PodType, std::size_t N>
00720 inline const_buffers_1 buffer(const PodType (&data)[N],
00721     std::size_t max_size_in_bytes)
00722 {
00723   return const_buffers_1(
00724       const_buffer(data,
00725         N * sizeof(PodType) < max_size_in_bytes
00726         ? N * sizeof(PodType) : max_size_in_bytes));
00727 }
00728 
00729 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) \
00730   || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
00731 
00732 // Borland C++ and Sun Studio think the overloads:
00733 //
00734 //   unspecified buffer(boost::array<PodType, N>& array ...);
00735 //
00736 // and
00737 //
00738 //   unspecified buffer(boost::array<const PodType, N>& array ...);
00739 //
00740 // are ambiguous. This will be worked around by using a buffer_types traits
00741 // class that contains typedefs for the appropriate buffer and container
00742 // classes, based on whether PodType is const or non-const.
00743 
00744 namespace detail {
00745 
00746 template <bool IsConst>
00747 struct buffer_types_base;
00748 
00749 template <>
00750 struct buffer_types_base<false>
00751 {
00752   typedef mutable_buffer buffer_type;
00753   typedef mutable_buffers_1 container_type;
00754 };
00755 
00756 template <>
00757 struct buffer_types_base<true>
00758 {
00759   typedef const_buffer buffer_type;
00760   typedef const_buffers_1 container_type;
00761 };
00762 
00763 template <typename PodType>
00764 struct buffer_types
00765   : public buffer_types_base<boost::is_const<PodType>::value>
00766 {
00767 };
00768 
00769 } // namespace detail
00770 
00771 template <typename PodType, std::size_t N>
00772 inline typename detail::buffer_types<PodType>::container_type
00773 buffer(boost::array<PodType, N>& data)
00774 {
00775   typedef typename asio::detail::buffer_types<PodType>::buffer_type
00776     buffer_type;
00777   typedef typename asio::detail::buffer_types<PodType>::container_type
00778     container_type;
00779   return container_type(
00780       buffer_type(data.c_array(), data.size() * sizeof(PodType)));
00781 }
00782 
00783 template <typename PodType, std::size_t N>
00784 inline typename detail::buffer_types<PodType>::container_type
00785 buffer(boost::array<PodType, N>& data, std::size_t max_size_in_bytes)
00786 {
00787   typedef typename asio::detail::buffer_types<PodType>::buffer_type
00788     buffer_type;
00789   typedef typename asio::detail::buffer_types<PodType>::container_type
00790     container_type;
00791   return container_type(
00792       buffer_type(data.c_array(),
00793         data.size() * sizeof(PodType) < max_size_in_bytes
00794         ? data.size() * sizeof(PodType) : max_size_in_bytes));
00795 }
00796 
00797 #else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
00798       // || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
00799 
00801 
00807 template <typename PodType, std::size_t N>
00808 inline mutable_buffers_1 buffer(boost::array<PodType, N>& data)
00809 {
00810   return mutable_buffers_1(
00811       mutable_buffer(data.c_array(), data.size() * sizeof(PodType)));
00812 }
00813 
00815 
00821 template <typename PodType, std::size_t N>
00822 inline mutable_buffers_1 buffer(boost::array<PodType, N>& data,
00823     std::size_t max_size_in_bytes)
00824 {
00825   return mutable_buffers_1(
00826       mutable_buffer(data.c_array(),
00827         data.size() * sizeof(PodType) < max_size_in_bytes
00828         ? data.size() * sizeof(PodType) : max_size_in_bytes));
00829 }
00830 
00832 
00838 template <typename PodType, std::size_t N>
00839 inline const_buffers_1 buffer(boost::array<const PodType, N>& data)
00840 {
00841   return const_buffers_1(
00842       const_buffer(data.data(), data.size() * sizeof(PodType)));
00843 }
00844 
00846 
00852 template <typename PodType, std::size_t N>
00853 inline const_buffers_1 buffer(boost::array<const PodType, N>& data,
00854     std::size_t max_size_in_bytes)
00855 {
00856   return const_buffers_1(
00857       const_buffer(data.data(),
00858         data.size() * sizeof(PodType) < max_size_in_bytes
00859         ? data.size() * sizeof(PodType) : max_size_in_bytes));
00860 }
00861 
00862 #endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
00863        // || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
00864 
00866 
00872 template <typename PodType, std::size_t N>
00873 inline const_buffers_1 buffer(const boost::array<PodType, N>& data)
00874 {
00875   return const_buffers_1(
00876       const_buffer(data.data(), data.size() * sizeof(PodType)));
00877 }
00878 
00880 
00886 template <typename PodType, std::size_t N>
00887 inline const_buffers_1 buffer(const boost::array<PodType, N>& data,
00888     std::size_t max_size_in_bytes)
00889 {
00890   return const_buffers_1(
00891       const_buffer(data.data(),
00892         data.size() * sizeof(PodType) < max_size_in_bytes
00893         ? data.size() * sizeof(PodType) : max_size_in_bytes));
00894 }
00895 
00897 
00906 template <typename PodType, typename Allocator>
00907 inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data)
00908 {
00909   return mutable_buffers_1(
00910       mutable_buffer(data.size() ? &data[0] : 0, data.size() * sizeof(PodType)
00911 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
00912         , detail::buffer_debug_check<
00913             typename std::vector<PodType, Allocator>::iterator
00914           >(data.begin())
00915 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
00916         ));
00917 }
00918 
00920 
00929 template <typename PodType, typename Allocator>
00930 inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data,
00931     std::size_t max_size_in_bytes)
00932 {
00933   return mutable_buffers_1(
00934       mutable_buffer(data.size() ? &data[0] : 0,
00935         data.size() * sizeof(PodType) < max_size_in_bytes
00936         ? data.size() * sizeof(PodType) : max_size_in_bytes
00937 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
00938         , detail::buffer_debug_check<
00939             typename std::vector<PodType, Allocator>::iterator
00940           >(data.begin())
00941 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
00942         ));
00943 }
00944 
00946 
00955 template <typename PodType, typename Allocator>
00956 inline const_buffers_1 buffer(
00957     const std::vector<PodType, Allocator>& data)
00958 {
00959   return const_buffers_1(
00960       const_buffer(data.size() ? &data[0] : 0, data.size() * sizeof(PodType)
00961 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
00962         , detail::buffer_debug_check<
00963             typename std::vector<PodType, Allocator>::const_iterator
00964           >(data.begin())
00965 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
00966         ));
00967 }
00968 
00970 
00979 template <typename PodType, typename Allocator>
00980 inline const_buffers_1 buffer(
00981     const std::vector<PodType, Allocator>& data, std::size_t max_size_in_bytes)
00982 {
00983   return const_buffers_1(
00984       const_buffer(data.size() ? &data[0] : 0,
00985         data.size() * sizeof(PodType) < max_size_in_bytes
00986         ? data.size() * sizeof(PodType) : max_size_in_bytes
00987 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
00988         , detail::buffer_debug_check<
00989             typename std::vector<PodType, Allocator>::const_iterator
00990           >(data.begin())
00991 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
00992         ));
00993 }
00994 
00996 
01002 inline const_buffers_1 buffer(const std::string& data)
01003 {
01004   return const_buffers_1(const_buffer(data.data(), data.size()
01005 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
01006         , detail::buffer_debug_check<std::string::const_iterator>(data.begin())
01007 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
01008         ));
01009 }
01010 
01012 
01021 inline const_buffers_1 buffer(const std::string& data,
01022     std::size_t max_size_in_bytes)
01023 {
01024   return const_buffers_1(
01025       const_buffer(data.data(),
01026         data.size() < max_size_in_bytes
01027         ? data.size() : max_size_in_bytes
01028 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
01029         , detail::buffer_debug_check<std::string::const_iterator>(data.begin())
01030 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
01031         ));
01032 }
01033 
01036 } // namespace asio
01037 
01038 #include "asio/detail/pop_options.hpp"
01039 
01040 #endif // ASIO_BUFFER_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


Castor
Author(s): Carpe Noctem
autogenerated on Fri Nov 8 2013 11:05:39