text: //
  // Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
  //
  // Distributed under the Boost Software License, Version 1.0. (See accompanying
  // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  //
  // Official repository: https://github.com/boostorg/beast
  //
  
  #ifndef BOOST_BEAST_IMPL_READ_SIZE_IPP
  #define BOOST_BEAST_IMPL_READ_SIZE_IPP
  
  namespace boost {
  namespace beast {
  
  namespace detail {
  
  template<class T, class = void>
  struct has_read_size_helper : std::false_type {};
  
  template<class T>
  struct has_read_size_helper<T, decltype(
      read_size_helper(std::declval<T&>(), 512),
      (void)0)> : std::true_type
  {
  };
  
  template<class DynamicBuffer>
  std::size_t
  read_size(DynamicBuffer& buffer,
      std::size_t max_size, std::true_type)
  {
      return read_size_helper(buffer, max_size);
  }
  
  template<class DynamicBuffer>
  std::size_t
  read_size(DynamicBuffer& buffer,
      std::size_t max_size, std::false_type)
  {
      static_assert(
          boost::asio::is_dynamic_buffer<DynamicBuffer>::value,
          "DynamicBuffer requirements not met");
      BOOST_ASSERT(max_size >= 1);
      auto const size = buffer.size();
      auto const limit = buffer.max_size() - size;
      BOOST_ASSERT(size <= buffer.max_size());
      return std::min<std::size_t>(
          std::max<std::size_t>(512, buffer.capacity() - size),
          std::min<std::size_t>(max_size, limit));
  }
  
  } // detail
  
  template<class DynamicBuffer>
  inline
  std::size_t
  read_size(
      DynamicBuffer& buffer, std::size_t max_size)
  {
      return detail::read_size(buffer, max_size,
          detail::has_read_size_helper<DynamicBuffer>{});
  }
  
  template<class DynamicBuffer>
  std::size_t
  read_size_or_throw(
      DynamicBuffer& buffer, std::size_t max_size)
  {
      auto const n = read_size(buffer, max_size);
      if(n == 0)
          BOOST_THROW_EXCEPTION(std::length_error{
              "buffer overflow"});
      return n;
  }
  
  } // beast
  } // boost
  
  #endif
  