Add data() and size() member functions to buffers.

The buffer_cast function is now deprecated.
diff --git a/asio/include/asio/basic_socket_streambuf.hpp b/asio/include/asio/basic_socket_streambuf.hpp
index f908d50..0a51459 100644
--- a/asio/include/asio/basic_socket_streambuf.hpp
+++ b/asio/include/asio/basic_socket_streambuf.hpp
@@ -444,7 +444,7 @@
       // Send all data in the output buffer.
       asio::const_buffer buffer =
         asio::buffer(pbase(), pptr() - pbase());
-      while (asio::buffer_size(buffer) > 0)
+      while (buffer.size() > 0)
       {
         if (timer_state_ == timer_has_expired)
         {
diff --git a/asio/include/asio/basic_streambuf.hpp b/asio/include/asio/basic_streambuf.hpp
index 5b7c5dc..d848255 100644
--- a/asio/include/asio/basic_streambuf.hpp
+++ b/asio/include/asio/basic_streambuf.hpp
@@ -151,7 +151,7 @@
    * while (i != bufs.end())
    * {
    *   const_buffer buf(*i++);
-   *   s += buffer_size(buf);
+   *   s += buf.size();
    * }
    * @endcode
    */
diff --git a/asio/include/asio/buffer.hpp b/asio/include/asio/buffer.hpp
index ba984b6..215b3dc 100644
--- a/asio/include/asio/buffer.hpp
+++ b/asio/include/asio/buffer.hpp
@@ -67,13 +67,6 @@
 class mutable_buffer;
 class const_buffer;
 
-namespace detail {
-void* buffer_cast_helper(const mutable_buffer&);
-const void* buffer_cast_helper(const const_buffer&);
-std::size_t buffer_size_helper(const mutable_buffer&);
-std::size_t buffer_size_helper(const const_buffer&);
-} // namespace detail
-
 /// Holds a buffer that can be modified.
 /**
  * The mutable_buffer class provides a safe representation of a buffer that can
@@ -82,16 +75,16 @@
  *
  * @par Accessing Buffer Contents
  *
- * The contents of a buffer may be accessed using the @ref buffer_size
- * and @ref buffer_cast functions:
+ * The contents of a buffer may be accessed using the @c data() and @c size()
+ * member functions:
  *
  * @code asio::mutable_buffer b1 = ...;
- * std::size_t s1 = asio::buffer_size(b1);
- * unsigned char* p1 = asio::buffer_cast<unsigned char*>(b1);
+ * std::size_t s1 = b1.size();
+ * unsigned char* p1 = static_cast<unsigned char*>(b1.data());
  * @endcode
  *
- * The asio::buffer_cast function permits violations of type safety, so
- * uses of it in application code should be carefully considered.
+ * The @c data() member function permits violations of type safety, so uses of
+ * it in application code should be carefully considered.
  */
 class mutable_buffer
 {
@@ -125,12 +118,23 @@
   }
 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
 
-private:
-  friend void* asio::detail::buffer_cast_helper(
-      const mutable_buffer& b);
-  friend std::size_t asio::detail::buffer_size_helper(
-      const mutable_buffer& b);
+  /// Get a pointer to the beginning of the memory range.
+  void* data() const
+  {
+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
+    if (size_ && debug_check_)
+      debug_check_();
+#endif // ASIO_ENABLE_BUFFER_DEBUGGING
+    return data_;
+  }
 
+  /// Get the size of the memory range.
+  std::size_t size() const
+  {
+    return size_;
+  }
+
+private:
   void* data_;
   std::size_t size_;
 
@@ -139,24 +143,6 @@
 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
 };
 
-namespace detail {
-
-inline void* buffer_cast_helper(const mutable_buffer& b)
-{
-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
-  if (b.size_ && b.debug_check_)
-    b.debug_check_();
-#endif // ASIO_ENABLE_BUFFER_DEBUGGING
-  return b.data_;
-}
-
-inline std::size_t buffer_size_helper(const mutable_buffer& b)
-{
-  return b.size_;
-}
-
-} // namespace detail
-
 /// Adapts a single modifiable buffer so that it meets the requirements of the
 /// MutableBufferSequence concept.
 class mutable_buffers_1
@@ -202,16 +188,16 @@
  *
  * @par Accessing Buffer Contents
  *
- * The contents of a buffer may be accessed using the @ref buffer_size
- * and @ref buffer_cast functions:
+ * The contents of a buffer may be accessed using the @c data() and @c size()
+ * member functions:
  *
  * @code asio::const_buffer b1 = ...;
- * std::size_t s1 = asio::buffer_size(b1);
- * const unsigned char* p1 = asio::buffer_cast<const unsigned char*>(b1);
+ * std::size_t s1 = b1.size();
+ * const unsigned char* p1 = static_cast<const unsigned char*>(b1.data());
  * @endcode
  *
- * The asio::buffer_cast function permits violations of type safety, so
- * uses of it in application code should be carefully considered.
+ * The @c data() member function permits violations of type safety, so uses of
+ * it in application code should be carefully considered.
  */
 class const_buffer
 {
@@ -232,8 +218,8 @@
 
   /// Construct a non-modifiable buffer from a modifiable one.
   const_buffer(const mutable_buffer& b)
-    : data_(asio::detail::buffer_cast_helper(b)),
-      size_(asio::detail::buffer_size_helper(b))
+    : data_(b.data()),
+      size_(b.size())
 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
       , debug_check_(b.get_debug_check())
 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
@@ -255,12 +241,23 @@
   }
 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
 
-private:
-  friend const void* asio::detail::buffer_cast_helper(
-      const const_buffer& b);
-  friend std::size_t asio::detail::buffer_size_helper(
-      const const_buffer& b);
+  /// Get a pointer to the beginning of the memory range.
+  const void* data() const
+  {
+#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
+    if (size_ && debug_check_)
+      debug_check_();
+#endif // ASIO_ENABLE_BUFFER_DEBUGGING
+    return data_;
+  }
 
+  /// Get the size of the memory range.
+  std::size_t size() const
+  {
+    return size_;
+  }
+
+private:
   const void* data_;
   std::size_t size_;
 
@@ -269,24 +266,6 @@
 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
 };
 
-namespace detail {
-
-inline const void* buffer_cast_helper(const const_buffer& b)
-{
-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
-  if (b.size_ && b.debug_check_)
-    b.debug_check_();
-#endif // ASIO_ENABLE_BUFFER_DEBUGGING
-  return b.data_;
-}
-
-inline std::size_t buffer_size_helper(const const_buffer& b)
-{
-  return b.size_;
-}
-
-} // namespace detail
-
 /// Adapts a single non-modifiable buffer so that it meets the requirements of
 /// the ConstBufferSequence concept.
 class const_buffers_1
@@ -398,25 +377,25 @@
 /// Get the number of bytes in a modifiable buffer.
 inline std::size_t buffer_size(const mutable_buffer& b)
 {
-  return detail::buffer_size_helper(b);
+  return b.size();
 }
 
 /// Get the number of bytes in a modifiable buffer.
 inline std::size_t buffer_size(const mutable_buffers_1& b)
 {
-  return detail::buffer_size_helper(b);
+  return b.size();
 }
 
 /// Get the number of bytes in a non-modifiable buffer.
 inline std::size_t buffer_size(const const_buffer& b)
 {
-  return detail::buffer_size_helper(b);
+  return b.size();
 }
 
 /// Get the number of bytes in a non-modifiable buffer.
 inline std::size_t buffer_size(const const_buffers_1& b)
 {
-  return detail::buffer_size_helper(b);
+  return b.size();
 }
 
 /// Get the total number of bytes in a buffer sequence.
@@ -435,17 +414,20 @@
   typename BufferSequence::const_iterator iter = b.begin();
   typename BufferSequence::const_iterator end = b.end();
   for (; iter != end; ++iter)
-    total_buffer_size += detail::buffer_size_helper(*iter);
+    total_buffer_size += iter->size();
 
   return total_buffer_size;
 }
 
 /*@}*/
 
+#if !defined(ASIO_NO_DEPRECATED)
+
 /** @defgroup buffer_cast asio::buffer_cast
  *
- * @brief The asio::buffer_cast function is used to obtain a pointer to
- * the underlying memory region associated with a buffer.
+ * @brief (Deprecated: Use the @c data() member function.) The
+ * asio::buffer_cast function is used to obtain a pointer to the underlying
+ * memory region associated with a buffer.
  *
  * @par Examples:
  *
@@ -468,28 +450,30 @@
 template <typename PointerToPodType>
 inline PointerToPodType buffer_cast(const mutable_buffer& b)
 {
-  return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
+  return static_cast<PointerToPodType>(b.data());
 }
 
 /// Cast a non-modifiable buffer to a specified pointer to POD type.
 template <typename PointerToPodType>
 inline PointerToPodType buffer_cast(const const_buffer& b)
 {
-  return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
+  return static_cast<PointerToPodType>(b.data());
 }
 
 /*@}*/
 
+#endif // !defined(ASIO_NO_DEPRECATED)
+
 /// Create a new modifiable buffer that is offset from the start of another.
 /**
  * @relates mutable_buffer
  */
 inline mutable_buffer operator+(const mutable_buffer& b, std::size_t start)
 {
-  if (start > buffer_size(b))
+  if (start > b.size())
     return mutable_buffer();
-  char* new_data = buffer_cast<char*>(b) + start;
-  std::size_t new_size = buffer_size(b) - start;
+  char* new_data = static_cast<char*>(b.data()) + start;
+  std::size_t new_size = b.size() - start;
   return mutable_buffer(new_data, new_size
 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
       , b.get_debug_check()
@@ -503,15 +487,7 @@
  */
 inline mutable_buffer operator+(std::size_t start, const mutable_buffer& b)
 {
-  if (start > buffer_size(b))
-    return mutable_buffer();
-  char* new_data = buffer_cast<char*>(b) + start;
-  std::size_t new_size = buffer_size(b) - start;
-  return mutable_buffer(new_data, new_size
-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
-      , b.get_debug_check()
-#endif // ASIO_ENABLE_BUFFER_DEBUGGING
-      );
+  return b + start;
 }
 
 /// Create a new non-modifiable buffer that is offset from the start of another.
@@ -520,10 +496,10 @@
  */
 inline const_buffer operator+(const const_buffer& b, std::size_t start)
 {
-  if (start > buffer_size(b))
+  if (start > b.size())
     return const_buffer();
-  const char* new_data = buffer_cast<const char*>(b) + start;
-  std::size_t new_size = buffer_size(b) - start;
+  const char* new_data = static_cast<const char*>(b.data()) + start;
+  std::size_t new_size = b.size() - start;
   return const_buffer(new_data, new_size
 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
       , b.get_debug_check()
@@ -537,15 +513,7 @@
  */
 inline const_buffer operator+(std::size_t start, const const_buffer& b)
 {
-  if (start > buffer_size(b))
-    return const_buffer();
-  const char* new_data = buffer_cast<const char*>(b) + start;
-  std::size_t new_size = buffer_size(b) - start;
-  return const_buffer(new_data, new_size
-#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
-      , b.get_debug_check()
-#endif // ASIO_ENABLE_BUFFER_DEBUGGING
-      );
+  return b + start;
 }
 
 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
@@ -630,24 +598,24 @@
  *
  * @par Accessing Buffer Contents
  *
- * The contents of a buffer may be accessed using the @ref buffer_size and
- * @ref buffer_cast functions:
+ * The contents of a buffer may be accessed using the @c data() and @c size()
+ * member functions:
  *
  * @code asio::mutable_buffer b1 = ...;
- * std::size_t s1 = asio::buffer_size(b1);
- * unsigned char* p1 = asio::buffer_cast<unsigned char*>(b1);
+ * std::size_t s1 = b1.size();
+ * unsigned char* p1 = static_cast<unsigned char*>(b1.data());
  *
  * asio::const_buffer b2 = ...;
- * std::size_t s2 = asio::buffer_size(b2);
- * const void* p2 = asio::buffer_cast<const void*>(b2); @endcode
+ * std::size_t s2 = b2.size();
+ * const void* p2 = b2.data(); @endcode
  *
- * The asio::buffer_cast function permits violations of type safety, so
+ * The @c data() member function permits violations of type safety, so
  * uses of it in application code should be carefully considered.
  *
- * For convenience, the @ref buffer_size function also works on buffer
- * sequences (that is, types meeting the ConstBufferSequence or
- * MutableBufferSequence type requirements). In this case, the function returns
- * the total size of all buffers in the sequence.
+ * For convenience, a @ref buffer_size function is provided that works with
+ * both buffers and buffer sequences (that is, types meeting the
+ * ConstBufferSequence or MutableBufferSequence type requirements). In this
+ * case, the function returns the total size of all buffers in the sequence.
  *
  * @par Buffer Copying
  *
@@ -757,16 +725,16 @@
 /**
  * @returns A mutable_buffers_1 value equivalent to:
  * @code mutable_buffers_1(
- *     buffer_cast<void*>(b),
- *     min(buffer_size(b), max_size_in_bytes)); @endcode
+ *     b.data(),
+ *     min(b.size(), max_size_in_bytes)); @endcode
  */
 inline mutable_buffers_1 buffer(const mutable_buffer& b,
     std::size_t max_size_in_bytes)
 {
   return mutable_buffers_1(
-      mutable_buffer(buffer_cast<void*>(b),
-        buffer_size(b) < max_size_in_bytes
-        ? buffer_size(b) : max_size_in_bytes
+      mutable_buffer(b.data(),
+        b.size() < max_size_in_bytes
+        ? b.size() : max_size_in_bytes
 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
         , b.get_debug_check()
 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
@@ -786,16 +754,16 @@
 /**
  * @returns A const_buffers_1 value equivalent to:
  * @code const_buffers_1(
- *     buffer_cast<const void*>(b),
- *     min(buffer_size(b), max_size_in_bytes)); @endcode
+ *     b.data(),
+ *     min(b.size(), max_size_in_bytes)); @endcode
  */
 inline const_buffers_1 buffer(const const_buffer& b,
     std::size_t max_size_in_bytes)
 {
   return const_buffers_1(
-      const_buffer(buffer_cast<const void*>(b),
-        buffer_size(b) < max_size_in_bytes
-        ? buffer_size(b) : max_size_in_bytes
+      const_buffer(b.data(),
+        b.size() < max_size_in_bytes
+        ? b.size() : max_size_in_bytes
 #if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
         , b.get_debug_check()
 #endif // ASIO_ENABLE_BUFFER_DEBUGGING
@@ -806,7 +774,8 @@
 /**
  * @returns <tt>mutable_buffers_1(data, size_in_bytes)</tt>.
  */
-inline mutable_buffers_1 buffer(void* data, std::size_t size_in_bytes)
+inline mutable_buffers_1 buffer(void* data,
+    std::size_t size_in_bytes)
 {
   return mutable_buffers_1(mutable_buffer(data, size_in_bytes));
 }
@@ -1744,10 +1713,10 @@
     const const_buffer& source)
 {
   using namespace std; // For memcpy.
-  std::size_t target_size = buffer_size(target);
-  std::size_t source_size = buffer_size(source);
+  std::size_t target_size = target.size();
+  std::size_t source_size = source.size();
   std::size_t n = target_size < source_size ? target_size : source_size;
-  memcpy(buffer_cast<void*>(target), buffer_cast<const void*>(source), n);
+  memcpy(target.data(), source.data(), n);
   return n;
 }
 
@@ -1860,7 +1829,7 @@
   typename ConstBufferSequence::const_iterator source_end = source.end();
 
   for (mutable_buffer target_buffer(target);
-      buffer_size(target_buffer) && source_iter != source_end; ++source_iter)
+      target_buffer.size() && source_iter != source_end; ++source_iter)
   {
     const_buffer source_buffer(*source_iter);
     std::size_t bytes_copied = buffer_copy(target_buffer, source_buffer);
@@ -2037,7 +2006,7 @@
   typename MutableBufferSequence::const_iterator target_end = target.end();
 
   for (const_buffer source_buffer(source);
-      buffer_size(source_buffer) && target_iter != target_end; ++target_iter)
+      source_buffer.size() && target_iter != target_end; ++target_iter)
   {
     mutable_buffer target_buffer(*target_iter);
     std::size_t bytes_copied = buffer_copy(target_buffer, source_buffer);
@@ -2185,7 +2154,7 @@
     std::size_t bytes_copied = buffer_copy(target_buffer, source_buffer);
     total_bytes_copied += bytes_copied;
 
-    if (bytes_copied == buffer_size(target_buffer))
+    if (bytes_copied == target_buffer.size())
     {
       ++target_iter;
       target_buffer_offset = 0;
@@ -2193,7 +2162,7 @@
     else
       target_buffer_offset += bytes_copied;
 
-    if (bytes_copied == buffer_size(source_buffer))
+    if (bytes_copied == source_buffer.size())
     {
       ++source_iter;
       source_buffer_offset = 0;
@@ -2702,7 +2671,7 @@
         source_buffer, max_bytes_to_copy - total_bytes_copied);
     total_bytes_copied += bytes_copied;
 
-    if (bytes_copied == buffer_size(target_buffer))
+    if (bytes_copied == target_buffer.size())
     {
       ++target_iter;
       target_buffer_offset = 0;
@@ -2710,7 +2679,7 @@
     else
       target_buffer_offset += bytes_copied;
 
-    if (bytes_copied == buffer_size(source_buffer))
+    if (bytes_copied == source_buffer.size())
     {
       ++source_iter;
       source_buffer_offset = 0;
diff --git a/asio/include/asio/buffers_iterator.hpp b/asio/include/asio/buffers_iterator.hpp
index 0404b12..c6eccfb 100644
--- a/asio/include/asio/buffers_iterator.hpp
+++ b/asio/include/asio/buffers_iterator.hpp
@@ -136,7 +136,7 @@
     while (new_iter.current_ != new_iter.end_)
     {
       new_iter.current_buffer_ = *new_iter.current_;
-      if (asio::buffer_size(new_iter.current_buffer_) > 0)
+      if (new_iter.current_buffer_.size() > 0)
         break;
       ++new_iter.current_;
     }
@@ -156,7 +156,7 @@
     while (new_iter.current_ != new_iter.end_)
     {
       buffer_type buffer = *new_iter.current_;
-      new_iter.position_ += asio::buffer_size(buffer);
+      new_iter.position_ += buffer.size();
       ++new_iter.current_;
     }
     return new_iter;
@@ -300,7 +300,8 @@
   // Dereference the iterator.
   reference dereference() const
   {
-    return buffer_cast<pointer>(current_buffer_)[current_buffer_position_];
+    return static_cast<pointer>(
+        current_buffer_.data())[current_buffer_position_];
   }
 
   // Compare two iterators for equality.
@@ -317,7 +318,7 @@
 
     // Check if the increment can be satisfied by the current buffer.
     ++current_buffer_position_;
-    if (current_buffer_position_ != asio::buffer_size(current_buffer_))
+    if (current_buffer_position_ != current_buffer_.size())
       return;
 
     // Find the next non-empty buffer.
@@ -326,7 +327,7 @@
     while (current_ != end_)
     {
       current_buffer_ = *current_;
-      if (asio::buffer_size(current_buffer_) > 0)
+      if (current_buffer_.size() > 0)
         return;
       ++current_;
     }
@@ -351,7 +352,7 @@
     {
       --iter;
       buffer_type buffer = *iter;
-      std::size_t buffer_size = asio::buffer_size(buffer);
+      std::size_t buffer_size = buffer.size();
       if (buffer_size > 0)
       {
         current_ = iter;
@@ -371,8 +372,7 @@
       for (;;)
       {
         std::ptrdiff_t current_buffer_balance
-          = asio::buffer_size(current_buffer_)
-          - current_buffer_position_;
+          = current_buffer_.size() - current_buffer_position_;
 
         // Check if the advance can be satisfied by the current buffer.
         if (current_buffer_balance > n)
@@ -431,7 +431,7 @@
         {
           --iter;
           buffer_type buffer = *iter;
-          std::size_t buffer_size = asio::buffer_size(buffer);
+          std::size_t buffer_size = buffer.size();
           if (buffer_size > 0)
           {
             current_ = iter;
diff --git a/asio/include/asio/detail/buffer_sequence_adapter.hpp b/asio/include/asio/detail/buffer_sequence_adapter.hpp
index 2f388c6..e3ad23d 100644
--- a/asio/include/asio/detail/buffer_sequence_adapter.hpp
+++ b/asio/include/asio/detail/buffer_sequence_adapter.hpp
@@ -50,15 +50,15 @@
   static void init_native_buffer(WSABUF& buf,
       const asio::mutable_buffer& buffer)
   {
-    buf.buf = asio::buffer_cast<char*>(buffer);
-    buf.len = static_cast<ULONG>(asio::buffer_size(buffer));
+    buf.buf = static_cast<char*>(buffer.data());
+    buf.len = static_cast<ULONG>(buffer.size());
   }
 
   static void init_native_buffer(WSABUF& buf,
       const asio::const_buffer& buffer)
   {
-    buf.buf = const_cast<char*>(asio::buffer_cast<const char*>(buffer));
-    buf.len = static_cast<ULONG>(asio::buffer_size(buffer));
+    buf.buf = const_cast<char*>(static_cast<const char*>(buffer.data()));
+    buf.len = static_cast<ULONG>(buffer.size());
   }
 #else // defined(ASIO_WINDOWS) || defined(__CYGWIN__)
   // The maximum number of buffers to support in a single operation.
@@ -80,16 +80,15 @@
   static void init_native_buffer(iovec& iov,
       const asio::mutable_buffer& buffer)
   {
-    init_iov_base(iov.iov_base, asio::buffer_cast<void*>(buffer));
-    iov.iov_len = asio::buffer_size(buffer);
+    init_iov_base(iov.iov_base, buffer.data());
+    iov.iov_len = buffer.size();
   }
 
   static void init_native_buffer(iovec& iov,
       const asio::const_buffer& buffer)
   {
-    init_iov_base(iov.iov_base, const_cast<void*>(
-          asio::buffer_cast<const void*>(buffer)));
-    iov.iov_len = asio::buffer_size(buffer);
+    init_iov_base(iov.iov_base, const_cast<void*>(buffer.data()));
+    iov.iov_len = buffer.size();
   }
 #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)
 };
@@ -109,7 +108,7 @@
     {
       Buffer buffer(*iter);
       init_native_buffer(buffers_[count_], buffer);
-      total_buffer_size_ += asio::buffer_size(buffer);
+      total_buffer_size_ += buffer.size();
     }
   }
 
@@ -134,7 +133,7 @@
     typename Buffers::const_iterator end = buffer_sequence.end();
     std::size_t i = 0;
     for (; iter != end && i < max_buffers; ++iter, ++i)
-      if (asio::buffer_size(Buffer(*iter)) > 0)
+      if (Buffer(*iter).size() > 0)
         return false;
     return true;
   }
@@ -146,7 +145,7 @@
     for (; iter != end; ++iter)
     {
       Buffer buffer(*iter);
-      asio::buffer_cast<const void*>(buffer);
+      buffer.data();
     }
   }
 
@@ -157,7 +156,7 @@
     for (; iter != end; ++iter)
     {
       Buffer buffer(*iter);
-      if (asio::buffer_size(buffer) != 0)
+      if (buffer.size() != 0)
         return buffer;
     }
     return Buffer();
@@ -178,7 +177,7 @@
       const asio::mutable_buffers_1& buffer_sequence)
   {
     init_native_buffer(buffer_, Buffer(buffer_sequence));
-    total_buffer_size_ = asio::buffer_size(buffer_sequence);
+    total_buffer_size_ = buffer_sequence.size();
   }
 
   native_buffer_type* buffers()
@@ -198,12 +197,12 @@
 
   static bool all_empty(const asio::mutable_buffers_1& buffer_sequence)
   {
-    return asio::buffer_size(buffer_sequence) == 0;
+    return buffer_sequence.size() == 0;
   }
 
   static void validate(const asio::mutable_buffers_1& buffer_sequence)
   {
-    asio::buffer_cast<const void*>(buffer_sequence);
+    buffer_sequence.data();
   }
 
   static Buffer first(const asio::mutable_buffers_1& buffer_sequence)
@@ -225,7 +224,7 @@
       const asio::const_buffers_1& buffer_sequence)
   {
     init_native_buffer(buffer_, Buffer(buffer_sequence));
-    total_buffer_size_ = asio::buffer_size(buffer_sequence);
+    total_buffer_size_ = buffer_sequence.size();
   }
 
   native_buffer_type* buffers()
@@ -245,12 +244,12 @@
 
   static bool all_empty(const asio::const_buffers_1& buffer_sequence)
   {
-    return asio::buffer_size(buffer_sequence) == 0;
+    return buffer_sequence.size() == 0;
   }
 
   static void validate(const asio::const_buffers_1& buffer_sequence)
   {
-    asio::buffer_cast<const void*>(buffer_sequence);
+    buffer_sequence.data();
   }
 
   static Buffer first(const asio::const_buffers_1& buffer_sequence)
@@ -273,8 +272,7 @@
   {
     init_native_buffer(buffers_[0], Buffer(buffer_sequence[0]));
     init_native_buffer(buffers_[1], Buffer(buffer_sequence[1]));
-    total_buffer_size_ = asio::buffer_size(buffer_sequence[0])
-      + asio::buffer_size(buffer_sequence[1]);
+    total_buffer_size_ = buffer_sequence[0].size() + buffer_sequence[1].size();
   }
 
   native_buffer_type* buffers()
@@ -294,19 +292,18 @@
 
   static bool all_empty(const boost::array<Elem, 2>& buffer_sequence)
   {
-    return asio::buffer_size(buffer_sequence[0]) == 0
-      && asio::buffer_size(buffer_sequence[1]) == 0;
+    return buffer_sequence[0].size() == 0 && buffer_sequence[1].size() == 0;
   }
 
   static void validate(const boost::array<Elem, 2>& buffer_sequence)
   {
-    asio::buffer_cast<const void*>(buffer_sequence[0]);
-    asio::buffer_cast<const void*>(buffer_sequence[1]);
+    buffer_sequence[0].data();
+    buffer_sequence[1].data();
   }
 
   static Buffer first(const boost::array<Elem, 2>& buffer_sequence)
   {
-    return Buffer(asio::buffer_size(buffer_sequence[0]) != 0
+    return Buffer(buffer_sequence[0].size() != 0
         ? buffer_sequence[0] : buffer_sequence[1]);
   }
 
@@ -327,8 +324,7 @@
   {
     init_native_buffer(buffers_[0], Buffer(buffer_sequence[0]));
     init_native_buffer(buffers_[1], Buffer(buffer_sequence[1]));
-    total_buffer_size_ = asio::buffer_size(buffer_sequence[0])
-      + asio::buffer_size(buffer_sequence[1]);
+    total_buffer_size_ = buffer_sequence[0].size() + buffer_sequence[1].size();
   }
 
   native_buffer_type* buffers()
@@ -348,19 +344,18 @@
 
   static bool all_empty(const std::array<Elem, 2>& buffer_sequence)
   {
-    return asio::buffer_size(buffer_sequence[0]) == 0
-      && asio::buffer_size(buffer_sequence[1]) == 0;
+    return buffer_sequence[0].size() == 0 && buffer_sequence[1].size() == 0;
   }
 
   static void validate(const std::array<Elem, 2>& buffer_sequence)
   {
-    asio::buffer_cast<const void*>(buffer_sequence[0]);
-    asio::buffer_cast<const void*>(buffer_sequence[1]);
+    buffer_sequence[0].data();
+    buffer_sequence[1].data();
   }
 
   static Buffer first(const std::array<Elem, 2>& buffer_sequence)
   {
-    return Buffer(asio::buffer_size(buffer_sequence[0]) != 0
+    return Buffer(buffer_sequence[0].size() != 0
         ? buffer_sequence[0] : buffer_sequence[1]);
   }
 
diff --git a/asio/include/asio/detail/consuming_buffers.hpp b/asio/include/asio/detail/consuming_buffers.hpp
index 37c9ffa..f6c6103 100644
--- a/asio/include/asio/detail/consuming_buffers.hpp
+++ b/asio/include/asio/detail/consuming_buffers.hpp
@@ -113,13 +113,13 @@
     if (!at_end_)
     {
       if (begin_remainder_ == end_remainder_
-          || offset_ + buffer_size(first_) >= max_size_)
+          || offset_ + first_.size() >= max_size_)
       {
         at_end_ = true;
       }
       else
       {
-        offset_ += buffer_size(first_);
+        offset_ += first_.size();
         first_ = buffer(*begin_remainder_++, max_size_ - offset_);
       }
     }
@@ -130,9 +130,8 @@
     if (at_end_ && other.at_end_)
       return true;
     return !at_end_ && !other.at_end_
-      && buffer_cast<const void*>(first_)
-        == buffer_cast<const void*>(other.first_)
-      && buffer_size(first_) == buffer_size(other.first_)
+      && first_.data() == other.first_.data()
+      && first_.size() == other.first_.size()
       && begin_remainder_ == other.begin_remainder_
       && end_remainder_ == other.end_remainder_;
   }
@@ -228,9 +227,9 @@
     // Remove buffers from the start until the specified size is reached.
     while (size > 0 && !at_end_)
     {
-      if (buffer_size(first_) <= size)
+      if (first_.size() <= size)
       {
-        size -= buffer_size(first_);
+        size -= first_.size();
         if (begin_remainder_ == buffers_.end())
           at_end_ = true;
         else
@@ -244,7 +243,7 @@
     }
 
     // Remove any more empty buffers at the start.
-    while (!at_end_ && buffer_size(first_) == 0)
+    while (!at_end_ && first_.size() == 0)
     {
       if (begin_remainder_ == buffers_.end())
         at_end_ = true;
diff --git a/asio/include/asio/detail/impl/buffer_sequence_adapter.ipp b/asio/include/asio/detail/impl/buffer_sequence_adapter.ipp
index f32764f..fcdad8f 100644
--- a/asio/include/asio/detail/impl/buffer_sequence_adapter.ipp
+++ b/asio/include/asio/detail/impl/buffer_sequence_adapter.ipp
@@ -39,16 +39,16 @@
 public:
   explicit winrt_buffer_impl(const asio::const_buffer& b)
   {
-    bytes_ = const_cast<byte*>(asio::buffer_cast<const byte*>(b));
-    length_ = asio::buffer_size(b);
-    capacity_ = asio::buffer_size(b);
+    bytes_ = const_cast<byte*>(static_cast<const byte*>(b.data()));
+    length_ = b.size();
+    capacity_ = b.size();
   }
 
   explicit winrt_buffer_impl(const asio::mutable_buffer& b)
   {
-    bytes_ = const_cast<byte*>(asio::buffer_cast<const byte*>(b));
+    bytes_ = static_cast<byte*>(b.data());
     length_ = 0;
-    capacity_ = asio::buffer_size(b);
+    capacity_ = b.size();
   }
 
   ~winrt_buffer_impl()
diff --git a/asio/include/asio/detail/impl/win_iocp_handle_service.ipp b/asio/include/asio/detail/impl/win_iocp_handle_service.ipp
index 1ede41d..d093a58 100644
--- a/asio/include/asio/detail/impl/win_iocp_handle_service.ipp
+++ b/asio/include/asio/detail/impl/win_iocp_handle_service.ipp
@@ -305,7 +305,7 @@
   }
 
   // A request to write 0 bytes on a handle is a no-op.
-  if (asio::buffer_size(buffer) == 0)
+  if (buffer.size() == 0)
   {
     ec = asio::error_code();
     return 0;
@@ -320,9 +320,8 @@
   // Write the data. 
   overlapped.Offset = offset & 0xFFFFFFFF;
   overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF;
-  BOOL ok = ::WriteFile(impl.handle_,
-      asio::buffer_cast<LPCVOID>(buffer),
-      static_cast<DWORD>(asio::buffer_size(buffer)), 0, &overlapped);
+  BOOL ok = ::WriteFile(impl.handle_, buffer.data(),
+      static_cast<DWORD>(buffer.size()), 0, &overlapped);
   if (!ok) 
   {
     DWORD last_error = ::GetLastError();
@@ -361,7 +360,7 @@
   {
     iocp_service_.on_completion(op, asio::error::bad_descriptor);
   }
-  else if (asio::buffer_size(buffer) == 0)
+  else if (buffer.size() == 0)
   {
     // A request to write 0 bytes on a handle is a no-op.
     iocp_service_.on_completion(op);
@@ -371,9 +370,8 @@
     DWORD bytes_transferred = 0;
     op->Offset = offset & 0xFFFFFFFF;
     op->OffsetHigh = (offset >> 32) & 0xFFFFFFFF;
-    BOOL ok = ::WriteFile(impl.handle_,
-        asio::buffer_cast<LPCVOID>(buffer),
-        static_cast<DWORD>(asio::buffer_size(buffer)),
+    BOOL ok = ::WriteFile(impl.handle_, buffer.data(),
+        static_cast<DWORD>(buffer.size()),
         &bytes_transferred, op);
     DWORD last_error = ::GetLastError();
     if (!ok && last_error != ERROR_IO_PENDING
@@ -399,7 +397,7 @@
   }
   
   // A request to read 0 bytes on a stream handle is a no-op.
-  if (asio::buffer_size(buffer) == 0)
+  if (buffer.size() == 0)
   {
     ec = asio::error_code();
     return 0;
@@ -414,9 +412,8 @@
   // Read some data.
   overlapped.Offset = offset & 0xFFFFFFFF;
   overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF;
-  BOOL ok = ::ReadFile(impl.handle_,
-      asio::buffer_cast<LPVOID>(buffer),
-      static_cast<DWORD>(asio::buffer_size(buffer)), 0, &overlapped);
+  BOOL ok = ::ReadFile(impl.handle_, buffer.data(),
+      static_cast<DWORD>(buffer.size()), 0, &overlapped);
   if (!ok) 
   {
     DWORD last_error = ::GetLastError();
@@ -469,7 +466,7 @@
   {
     iocp_service_.on_completion(op, asio::error::bad_descriptor);
   }
-  else if (asio::buffer_size(buffer) == 0)
+  else if (buffer.size() == 0)
   {
     // A request to read 0 bytes on a handle is a no-op.
     iocp_service_.on_completion(op);
@@ -479,9 +476,8 @@
     DWORD bytes_transferred = 0;
     op->Offset = offset & 0xFFFFFFFF;
     op->OffsetHigh = (offset >> 32) & 0xFFFFFFFF;
-    BOOL ok = ::ReadFile(impl.handle_,
-        asio::buffer_cast<LPVOID>(buffer),
-        static_cast<DWORD>(asio::buffer_size(buffer)),
+    BOOL ok = ::ReadFile(impl.handle_, buffer.data(),
+        static_cast<DWORD>(buffer.size()),
         &bytes_transferred, op);
     DWORD last_error = ::GetLastError();
     if (!ok && last_error != ERROR_IO_PENDING
diff --git a/asio/include/asio/impl/read.hpp b/asio/include/asio/impl/read.hpp
index 031a5b3..8545732 100644
--- a/asio/include/asio/impl/read.hpp
+++ b/asio/include/asio/impl/read.hpp
@@ -344,7 +344,7 @@
           total_transferred_ += bytes_transferred;
           if ((!ec && bytes_transferred == 0)
               || (n = this->check_for_completion(ec, total_transferred_)) == 0
-              || total_transferred_ == asio::buffer_size(buffer_))
+              || total_transferred_ == buffer_.size())
             break;
         }
 
@@ -408,8 +408,8 @@
           boost::array<asio::mutable_buffer, 2> >::type bufs = {{
         asio::mutable_buffer(buffers_[0]),
         asio::mutable_buffer(buffers_[1]) }};
-      std::size_t buffer_size0 = asio::buffer_size(bufs[0]);
-      std::size_t buffer_size1 = asio::buffer_size(bufs[1]);
+      std::size_t buffer_size0 = bufs[0].size();
+      std::size_t buffer_size1 = bufs[1].size();
       std::size_t n = 0;
       switch (start_ = start)
       {
@@ -421,7 +421,7 @@
           bufs[1] = asio::buffer(
               bufs[1] + (total_transferred_ < buffer_size0
                 ? 0 : total_transferred_ - buffer_size0),
-              n - asio::buffer_size(bufs[0]));
+              n - bufs[0].size());
           stream_.async_read_some(bufs, ASIO_MOVE_CAST(read_op)(*this));
           return; default:
           total_transferred_ += bytes_transferred;
@@ -493,8 +493,8 @@
           std::array<asio::mutable_buffer, 2> >::type bufs = {{
         asio::mutable_buffer(buffers_[0]),
         asio::mutable_buffer(buffers_[1]) }};
-      std::size_t buffer_size0 = asio::buffer_size(bufs[0]);
-      std::size_t buffer_size1 = asio::buffer_size(bufs[1]);
+      std::size_t buffer_size0 = bufs[0].size();
+      std::size_t buffer_size1 = bufs[1].size();
       std::size_t n = 0;
       switch (start_ = start)
       {
@@ -506,7 +506,7 @@
           bufs[1] = asio::buffer(
               bufs[1] + (total_transferred_ < buffer_size0
                 ? 0 : total_transferred_ - buffer_size0),
-              n - asio::buffer_size(bufs[0]));
+              n - bufs[0].size());
           stream_.async_read_some(bufs, ASIO_MOVE_CAST(read_op)(*this));
           return; default:
           total_transferred_ += bytes_transferred;
diff --git a/asio/include/asio/impl/read_at.hpp b/asio/include/asio/impl/read_at.hpp
index 634f035..22882c6 100644
--- a/asio/include/asio/impl/read_at.hpp
+++ b/asio/include/asio/impl/read_at.hpp
@@ -295,7 +295,7 @@
           total_transferred_ += bytes_transferred;
           if ((!ec && bytes_transferred == 0)
               || (n = this->check_for_completion(ec, total_transferred_)) == 0
-              || total_transferred_ == asio::buffer_size(buffer_))
+              || total_transferred_ == buffer_.size())
             break;
         }
 
@@ -364,8 +364,8 @@
           boost::array<asio::mutable_buffer, 2> >::type bufs = {{
         asio::mutable_buffer(buffers_[0]),
         asio::mutable_buffer(buffers_[1]) }};
-      std::size_t buffer_size0 = asio::buffer_size(bufs[0]);
-      std::size_t buffer_size1 = asio::buffer_size(bufs[1]);
+      std::size_t buffer_size0 = bufs[0].size();
+      std::size_t buffer_size1 = bufs[1].size();
       std::size_t n = 0;
       switch (start_ = start)
       {
@@ -377,7 +377,7 @@
           bufs[1] = asio::buffer(
               bufs[1] + (total_transferred_ < buffer_size0
                 ? 0 : total_transferred_ - buffer_size0),
-              n - asio::buffer_size(bufs[0]));
+              n - bufs[0].size());
           device_.async_read_some_at(offset_ + total_transferred_,
               bufs, ASIO_MOVE_CAST(read_at_op)(*this));
           return; default:
@@ -455,8 +455,8 @@
           std::array<asio::mutable_buffer, 2> >::type bufs = {{
         asio::mutable_buffer(buffers_[0]),
         asio::mutable_buffer(buffers_[1]) }};
-      std::size_t buffer_size0 = asio::buffer_size(bufs[0]);
-      std::size_t buffer_size1 = asio::buffer_size(bufs[1]);
+      std::size_t buffer_size0 = bufs[0].size();
+      std::size_t buffer_size1 = bufs[1].size();
       std::size_t n = 0;
       switch (start_ = start)
       {
@@ -468,7 +468,7 @@
           bufs[1] = asio::buffer(
               bufs[1] + (total_transferred_ < buffer_size0
                 ? 0 : total_transferred_ - buffer_size0),
-              n - asio::buffer_size(bufs[0]));
+              n - bufs[0].size());
           device_.async_read_some_at(offset_ + total_transferred_,
               bufs, ASIO_MOVE_CAST(read_at_op)(*this));
           return; default:
diff --git a/asio/include/asio/impl/write.hpp b/asio/include/asio/impl/write.hpp
index 34f882e..4fbfc44 100644
--- a/asio/include/asio/impl/write.hpp
+++ b/asio/include/asio/impl/write.hpp
@@ -328,7 +328,7 @@
           total_transferred_ += bytes_transferred;
           if ((!ec && bytes_transferred == 0)
               || (n = this->check_for_completion(ec, total_transferred_)) == 0
-              || total_transferred_ == asio::buffer_size(buffer_))
+              || total_transferred_ == buffer_.size())
             break;
         }
 
@@ -404,7 +404,7 @@
           total_transferred_ += bytes_transferred;
           if ((!ec && bytes_transferred == 0)
               || (n = this->check_for_completion(ec, total_transferred_)) == 0
-              || total_transferred_ == asio::buffer_size(buffer_))
+              || total_transferred_ == buffer_.size())
             break;
         }
 
@@ -468,8 +468,8 @@
           boost::array<asio::const_buffer, 2> >::type bufs = {{
         asio::const_buffer(buffers_[0]),
         asio::const_buffer(buffers_[1]) }};
-      std::size_t buffer_size0 = asio::buffer_size(bufs[0]);
-      std::size_t buffer_size1 = asio::buffer_size(bufs[1]);
+      std::size_t buffer_size0 = bufs[0].size();
+      std::size_t buffer_size1 = bufs[1].size();
       std::size_t n = 0;
       switch (start_ = start)
       {
@@ -481,7 +481,7 @@
           bufs[1] = asio::buffer(
               bufs[1] + (total_transferred_ < buffer_size0
                 ? 0 : total_transferred_ - buffer_size0),
-              n - asio::buffer_size(bufs[0]));
+              n - bufs[0].size());
           stream_.async_write_some(bufs, ASIO_MOVE_CAST(write_op)(*this));
           return; default:
           total_transferred_ += bytes_transferred;
@@ -553,8 +553,8 @@
           std::array<asio::const_buffer, 2> >::type bufs = {{
         asio::const_buffer(buffers_[0]),
         asio::const_buffer(buffers_[1]) }};
-      std::size_t buffer_size0 = asio::buffer_size(bufs[0]);
-      std::size_t buffer_size1 = asio::buffer_size(bufs[1]);
+      std::size_t buffer_size0 = bufs[0].size();
+      std::size_t buffer_size1 = bufs[1].size();
       std::size_t n = 0;
       switch (start_ = start)
       {
@@ -566,7 +566,7 @@
           bufs[1] = asio::buffer(
               bufs[1] + (total_transferred_ < buffer_size0
                 ? 0 : total_transferred_ - buffer_size0),
-              n - asio::buffer_size(bufs[0]));
+              n - bufs[0].size());
           stream_.async_write_some(bufs, ASIO_MOVE_CAST(write_op)(*this));
           return; default:
           total_transferred_ += bytes_transferred;
diff --git a/asio/include/asio/impl/write_at.hpp b/asio/include/asio/impl/write_at.hpp
index fb539df..9303c5c 100644
--- a/asio/include/asio/impl/write_at.hpp
+++ b/asio/include/asio/impl/write_at.hpp
@@ -281,7 +281,7 @@
           total_transferred_ += bytes_transferred;
           if ((!ec && bytes_transferred == 0)
               || (n = this->check_for_completion(ec, total_transferred_)) == 0
-              || total_transferred_ == asio::buffer_size(buffer_))
+              || total_transferred_ == buffer_.size())
             break;
         }
 
@@ -361,7 +361,7 @@
           total_transferred_ += bytes_transferred;
           if ((!ec && bytes_transferred == 0)
               || (n = this->check_for_completion(ec, total_transferred_)) == 0
-              || total_transferred_ == asio::buffer_size(buffer_))
+              || total_transferred_ == buffer_.size())
             break;
         }
 
@@ -430,8 +430,8 @@
           boost::array<asio::const_buffer, 2> >::type bufs = {{
         asio::const_buffer(buffers_[0]),
         asio::const_buffer(buffers_[1]) }};
-      std::size_t buffer_size0 = asio::buffer_size(bufs[0]);
-      std::size_t buffer_size1 = asio::buffer_size(bufs[1]);
+      std::size_t buffer_size0 = bufs[0].size();
+      std::size_t buffer_size1 = bufs[1].size();
       std::size_t n = 0;
       switch (start_ = start)
       {
@@ -443,7 +443,7 @@
           bufs[1] = asio::buffer(
               bufs[1] + (total_transferred_ < buffer_size0
                 ? 0 : total_transferred_ - buffer_size0),
-              n - asio::buffer_size(bufs[0]));
+              n - bufs[0].size());
           device_.async_write_some_at(offset_ + total_transferred_,
               bufs, ASIO_MOVE_CAST(write_at_op)(*this));
           return; default:
@@ -521,8 +521,8 @@
           std::array<asio::const_buffer, 2> >::type bufs = {{
         asio::const_buffer(buffers_[0]),
         asio::const_buffer(buffers_[1]) }};
-      std::size_t buffer_size0 = asio::buffer_size(bufs[0]);
-      std::size_t buffer_size1 = asio::buffer_size(bufs[1]);
+      std::size_t buffer_size0 = bufs[0].size();
+      std::size_t buffer_size1 = bufs[1].size();
       std::size_t n = 0;
       switch (start_ = start)
       {
@@ -534,7 +534,7 @@
           bufs[1] = asio::buffer(
               bufs[1] + (total_transferred_ < buffer_size0
                 ? 0 : total_transferred_ - buffer_size0),
-              n - asio::buffer_size(bufs[0]));
+              n - bufs[0].size());
           device_.async_write_some_at(offset_ + total_transferred_,
               bufs, ASIO_MOVE_CAST(write_at_op)(*this));
           return; default:
diff --git a/asio/include/asio/ssl/detail/buffered_handshake_op.hpp b/asio/include/asio/ssl/detail/buffered_handshake_op.hpp
index 9e1d983..c18f314 100644
--- a/asio/include/asio/ssl/detail/buffered_handshake_op.hpp
+++ b/asio/include/asio/ssl/detail/buffered_handshake_op.hpp
@@ -58,9 +58,9 @@
         const_buffer buffer(*iter);
 
         // Skip over any buffers which have already been consumed by the engine.
-        if (bytes_transferred >= accumulated_size + buffer_size(buffer))
+        if (bytes_transferred >= accumulated_size + buffer.size())
         {
-          accumulated_size += buffer_size(buffer);
+          accumulated_size += buffer.size();
           ++iter;
           continue;
         }
@@ -73,9 +73,9 @@
 
         // Pass the buffer to the engine, and update the bytes transferred to
         // reflect the total number of bytes consumed so far.
-        bytes_transferred += buffer_size(buffer);
+        bytes_transferred += buffer.size();
         buffer = eng.put_input(buffer);
-        bytes_transferred -= buffer_size(buffer);
+        bytes_transferred -= buffer.size();
         break;
       }
     }
diff --git a/asio/include/asio/ssl/detail/impl/engine.ipp b/asio/include/asio/ssl/detail/impl/engine.ipp
index 2e4a39d..b59cf18 100644
--- a/asio/include/asio/ssl/detail/impl/engine.ipp
+++ b/asio/include/asio/ssl/detail/impl/engine.ipp
@@ -141,37 +141,35 @@
 engine::want engine::write(const asio::const_buffer& data,
     asio::error_code& ec, std::size_t& bytes_transferred)
 {
-  if (asio::buffer_size(data) == 0)
+  if (data.size() == 0)
   {
     ec = asio::error_code();
     return engine::want_nothing;
   }
 
   return perform(&engine::do_write,
-      const_cast<void*>(asio::buffer_cast<const void*>(data)),
-      asio::buffer_size(data), ec, &bytes_transferred);
+      const_cast<void*>(data.data()),
+      data.size(), ec, &bytes_transferred);
 }
 
 engine::want engine::read(const asio::mutable_buffer& data,
     asio::error_code& ec, std::size_t& bytes_transferred)
 {
-  if (asio::buffer_size(data) == 0)
+  if (data.size() == 0)
   {
     ec = asio::error_code();
     return engine::want_nothing;
   }
 
-  return perform(&engine::do_read,
-      asio::buffer_cast<void*>(data),
-      asio::buffer_size(data), ec, &bytes_transferred);
+  return perform(&engine::do_read, data.data(),
+      data.size(), ec, &bytes_transferred);
 }
 
 asio::mutable_buffers_1 engine::get_output(
     const asio::mutable_buffer& data)
 {
   int length = ::BIO_read(ext_bio_,
-      asio::buffer_cast<void*>(data),
-      static_cast<int>(asio::buffer_size(data)));
+      data.data(), static_cast<int>(data.size()));
 
   return asio::buffer(data,
       length > 0 ? static_cast<std::size_t>(length) : 0);
@@ -181,8 +179,7 @@
     const asio::const_buffer& data)
 {
   int length = ::BIO_write(ext_bio_,
-      asio::buffer_cast<const void*>(data),
-      static_cast<int>(asio::buffer_size(data)));
+      data.data(), static_cast<int>(data.size()));
 
   return asio::buffer(data +
       (length > 0 ? static_cast<std::size_t>(length) : 0));
diff --git a/asio/include/asio/ssl/detail/io.hpp b/asio/include/asio/ssl/detail/io.hpp
index 86781a4..3d5bed6 100644
--- a/asio/include/asio/ssl/detail/io.hpp
+++ b/asio/include/asio/ssl/detail/io.hpp
@@ -38,7 +38,7 @@
 
     // If the input buffer is empty then we need to read some more data from
     // the underlying transport.
-    if (asio::buffer_size(core.input_) == 0)
+    if (core.input_.size() == 0)
       core.input_ = asio::buffer(core.input_buffer_,
           next_layer.read_some(core.input_buffer_, ec));
 
@@ -138,7 +138,7 @@
 
           // If the input buffer already has data in it we can pass it to the
           // engine and then retry the operation immediately.
-          if (asio::buffer_size(core_.input_) != 0)
+          if (core_.input_.size() != 0)
           {
             core_.input_ = core_.engine_.put_input(core_.input_);
             continue;
diff --git a/asio/include/asio/ssl/impl/context.ipp b/asio/include/asio/ssl/impl/context.ipp
index ed55ef1..08705e7 100644
--- a/asio/include/asio/ssl/impl/context.ipp
+++ b/asio/include/asio/ssl/impl/context.ipp
@@ -427,8 +427,8 @@
   if (format == context_base::asn1)
   {
     if (::SSL_CTX_use_certificate_ASN1(handle_,
-          static_cast<int>(buffer_size(certificate)),
-          buffer_cast<const unsigned char*>(certificate)) == 1)
+          static_cast<int>(certificate.size()),
+          static_cast<const unsigned char*>(certificate.data())) == 1)
     {
       ec = asio::error_code();
       return ec;
@@ -943,8 +943,8 @@
 BIO* context::make_buffer_bio(const const_buffer& b)
 {
   return ::BIO_new_mem_buf(
-      const_cast<void*>(buffer_cast<const void*>(b)),
-      static_cast<int>(buffer_size(b)));
+      const_cast<void*>(b.data()),
+      static_cast<int>(b.size()));
 }
 
 } // namespace ssl
diff --git a/asio/src/doc/overview/buffers.qbk b/asio/src/doc/overview/buffers.qbk
index 8ca09c2..4140811 100644
--- a/asio/src/doc/overview/buffers.qbk
+++ b/asio/src/doc/overview/buffers.qbk
@@ -45,7 +45,7 @@
   mechanisms for automatically determining the size of a buffer from an array,
   `boost::array` or `std::vector` of POD elements, or from a `std::string`.
 
-* Type safety violations must be explicitly requested using the `buffer_cast`
+* The underlying memory is explicitly accessed using the `data()` member
   function. In general an application should never need to do this, but it is
   required by the library implementation to pass the raw memory to the
   underlying operating system functions.
diff --git a/asio/src/tests/unit/buffer.cpp b/asio/src/tests/unit/buffer.cpp
index 5dc584e..a30045d 100644
--- a/asio/src/tests/unit/buffer.cpp
+++ b/asio/src/tests/unit/buffer.cpp
@@ -68,6 +68,14 @@
     mutable_buffer mb2(void_ptr_data, 1024);
     mutable_buffer mb3(mb1);
 
+    // mutable_buffer functions.
+
+    void* ptr1 = mb1.data();
+    (void)ptr1;
+
+    std::size_t n1 = mb1.size();
+    (void)n1;
+
     // mutable_buffer operators.
 
     mb1 = mb2 + 128;
@@ -92,6 +100,14 @@
     const_buffer cb3(cb1);
     const_buffer cb4(mb1);
 
+    // const_buffer functions.
+
+    const void* ptr2 = cb1.data();
+    (void)ptr2;
+
+    std::size_t n2 = cb1.size();
+    (void)n2;
+
     // const_buffer operators.
 
     cb1 = cb2 + 128;
@@ -126,10 +142,12 @@
 
     // buffer_cast function overloads.
 
-    void* ptr1 = buffer_cast<void*>(mb1);
-    (void)ptr1;
-    const void* ptr2 = buffer_cast<const void*>(cb1);
-    (void)ptr2;
+#if !defined(ASIO_NO_DEPRECATED)
+    void* ptr3 = buffer_cast<void*>(mb1);
+    (void)ptr3;
+    const void* ptr4 = buffer_cast<const void*>(cb1);
+    (void)ptr4;
+#endif // !defined(ASIO_NO_DEPRECATED)
 
     // buffer function overloads.